diff --git a/go.mod b/go.mod index 66e53c6..c6f6993 100644 --- a/go.mod +++ b/go.mod @@ -2,13 +2,12 @@ module tuxpa.in/t/wm go 1.19 -replace github.com/jezek/xgb v1.1.0 => ./xgb +replace github.com/jezek/xgb v1.1.0 => ./vend/xgb -replace github.com/jezek/xgbutil v0.0.0-20230603163917-04188eb39cf0 => ./xgbutil - -require github.com/jezek/xgb v1.1.0 +replace github.com/jezek/xgbutil v0.0.0-20230603163917-04188eb39cf0 => ./vend/xgbutil require ( + github.com/jezek/xgb v1.1.0 github.com/jezek/xgbutil v0.0.0-20230603163917-04188eb39cf0 github.com/stretchr/testify v1.8.4 ) diff --git a/vend/xgb/.gitignore b/vend/xgb/.gitignore new file mode 100644 index 0000000..179f830 --- /dev/null +++ b/vend/xgb/.gitignore @@ -0,0 +1,2 @@ +xgbgen/xgbgen +.*.swp diff --git a/vend/xgb/AUTHORS b/vend/xgb/AUTHORS new file mode 100644 index 0000000..08fc0cd --- /dev/null +++ b/vend/xgb/AUTHORS @@ -0,0 +1,18 @@ +Andrew Gallant is the maintainer of this fork. What follows is the original +list of authors for the x-go-binding. + +# This is the official list of XGB authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. + +Anthony Martin +Firmansyah Adiputra +Google Inc. +Scott Lawrence +Tor Andersson diff --git a/vend/xgb/CONTRIBUTORS b/vend/xgb/CONTRIBUTORS new file mode 100644 index 0000000..46dc4b0 --- /dev/null +++ b/vend/xgb/CONTRIBUTORS @@ -0,0 +1,39 @@ +Andrew Gallant is the maintainer of this fork. What follows is the original +list of contributors for the x-go-binding. + +# This is the official list of people who can contribute +# (and typically have contributed) code to the XGB repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# The submission process automatically checks to make sure +# that people submitting code are listed in this file (by email address). +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# http://code.google.com/legal/individual-cla-v1.0.html +# http://code.google.com/legal/corporate-cla-v1.0.html +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. + +# Names should be added to this file like so: +# Name + +# Please keep the list sorted. + +Anthony Martin +Firmansyah Adiputra +Ian Lance Taylor +Nigel Tao +Robert Griesemer +Russ Cox +Scott Lawrence +Tor Andersson diff --git a/vend/xgb/LICENSE b/vend/xgb/LICENSE new file mode 100644 index 0000000..d99cd90 --- /dev/null +++ b/vend/xgb/LICENSE @@ -0,0 +1,42 @@ +// Copyright (c) 2009 The XGB Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Subject to the terms and conditions of this License, Google hereby +// grants to You a perpetual, worldwide, non-exclusive, no-charge, +// royalty-free, irrevocable (except as stated in this section) patent +// license to make, have made, use, offer to sell, sell, import, and +// otherwise transfer this implementation of XGB, where such license +// applies only to those patent claims licensable by Google that are +// necessarily infringed by use of this implementation of XGB. If You +// institute patent litigation against any entity (including a +// cross-claim or counterclaim in a lawsuit) alleging that this +// implementation of XGB or a Contribution incorporated within this +// implementation of XGB constitutes direct or contributory patent +// infringement, then any patent licenses granted to You under this +// License for this implementation of XGB shall terminate as of the date +// such litigation is filed. diff --git a/vend/xgb/Makefile b/vend/xgb/Makefile new file mode 100644 index 0000000..c0ee531 --- /dev/null +++ b/vend/xgb/Makefile @@ -0,0 +1,80 @@ +# This Makefile is used by the developer. It is not needed in any way to build +# a checkout of the XGB repository. +# It will be useful, however, if you are hacking at the code generator. +# i.e., after making a change to the code generator, run 'make' in the +# xgb directory. This will build xgbgen and regenerate each sub-package. +# 'make test' will then run any appropriate tests (just tests xproto right now). +# 'make bench' will test a couple of benchmarks. +# 'make build-all' will then try to build each extension. This isn't strictly +# necessary, but it's a good idea to make sure each sub-package is a valid +# Go package. + +# My path to the X protocol XML descriptions. +ifndef XPROTO +XPROTO=/usr/share/xcb +endif + +# All of the XML files in my /usr/share/xcb directory EXCEPT XKB. -_- +# This is intended to build xgbgen and generate Go code for each supported +# extension. +all: build-xgbgen \ + bigreq.xml composite.xml damage.xml dpms.xml dri2.xml \ + ge.xml glx.xml randr.xml record.xml render.xml res.xml \ + screensaver.xml shape.xml shm.xml xc_misc.xml \ + xevie.xml xf86dri.xml xf86vidmode.xml xfixes.xml xinerama.xml \ + xprint.xml xproto.xml xselinux.xml xtest.xml \ + xvmc.xml xv.xml + +build-xgbgen: + (cd xgbgen && go build) + +# Builds each individual sub-package to make sure its valid Go code. +build-all: bigreq.b composite.b damage.b dpms.b dri2.b ge.b glx.b randr.b \ + record.b render.b res.b screensaver.b shape.b shm.b xcmisc.b \ + xevie.b xf86dri.b xf86vidmode.b xfixes.b xinerama.b \ + xprint.b xproto.b xselinux.b xtest.b xv.b xvmc.b + +%.b: + (cd $* ; go build) + +# Installs each individual sub-package. +install: bigreq.i composite.i damage.i dpms.i dri2.i ge.i glx.i randr.i \ + record.i render.i res.i screensaver.i shape.i shm.i xcmisc.i \ + xevie.i xf86dri.i xf86vidmode.i xfixes.i xinerama.i \ + xprint.i xproto.i xselinux.i xtest.i xv.i xvmc.i + go install + +%.i: + (cd $* ; go install) + +# xc_misc is special because it has an underscore. +# There's probably a way to do this better, but Makefiles aren't my strong suit. +xc_misc.xml: build-xgbgen + mkdir -p xcmisc + xgbgen/xgbgen --proto-path $(XPROTO) $(XPROTO)/xc_misc.xml > xcmisc/xcmisc.go + +%.xml: build-xgbgen + mkdir -p $* + xgbgen/xgbgen --proto-path $(XPROTO) $(XPROTO)/$*.xml > $*/$*.go + +# Just test the xproto core protocol for now. +test: + (cd xproto ; go test) + +# Force all xproto benchmarks to run and no tests. +bench: + (cd xproto ; go test -run 'nomatch' -bench '.*' -cpu 1,2,3,6) + +# gofmt all non-auto-generated code. +# (auto-generated code is already gofmt'd.) +# Also do a column check (80 cols) after a gofmt. +# But don't check columns on auto-generated code, since I don't care if they +# break 80 cols. +gofmt: + gofmt -w *.go xgbgen/*.go examples/*.go examples/*/*.go xproto/xproto_test.go + colcheck *.go xgbgen/*.go examples/*.go examples/*/*.go xproto/xproto_test.go + +push: + git push origin master + git push github master + diff --git a/vend/xgb/README b/vend/xgb/README new file mode 100644 index 0000000..986b70c --- /dev/null +++ b/vend/xgb/README @@ -0,0 +1,62 @@ +XGB is the X Go Binding, which is a low-level API to communicate with the +core X protocol and many of the X extensions. It is closely modeled after +XCB and xpyb. + +It is thread safe and gets immediate improvement from parallelism when +GOMAXPROCS > 1. (See the benchmarks in xproto/xproto_test.go for evidence.) + +Please see doc.go for more info. + +Note that unless you know you need XGB, you can probably make your life +easier by using a slightly higher level library: xgbutil. + +This is a fork of github.com/BurntSushi/xgb + +Quick Usage +=========== +go get github.com/jezek/xgb +go run go/path/src/github.com/jezek/xgb/examples/create-window/main.go + +jezek's Fork +============ +I've forked the XGB repository from BurntSushi's github to apply some +patches which caused panics and memory leaks upon close and tests were added, +to test multiple server close scenarios. + +BurntSushi's Fork +================= +I've forked the XGB repository from Google Code due to inactivty upstream. + +Godoc documentation can be found here: +https://godoc.org/github.com/BurntSushi/xgb + +Much of the code has been rewritten in an effort to support thread safety +and multiple extensions. Namely, go_client.py has been thrown away in favor +of an xgbgen package. + +The biggest parts that *haven't* been rewritten by me are the connection and +authentication handshakes. They're inherently messy, and there's really no +reason to re-work them. The rest of XGB has been completely rewritten. + +I like to release my code under the WTFPL, but since I'm starting with someone +else's work, I'm leaving the original license/contributor/author information +in tact. + +I suppose I can legitimately release xgbgen under the WTFPL. To be fair, it is +at least as complex as XGB itself. *sigh* + +What follows is the original README: + +XGB README +========== +XGB is the X protocol Go language Binding. + +It is the Go equivalent of XCB, the X protocol C-language Binding +(http://xcb.freedesktop.org/). + +Unless otherwise noted, the XGB source files are distributed +under the BSD-style license found in the LICENSE file. + +Contributions should follow the same procedure as for the Go project: +http://golang.org/doc/contribute.html + diff --git a/vend/xgb/STYLE b/vend/xgb/STYLE new file mode 100644 index 0000000..b827c3c --- /dev/null +++ b/vend/xgb/STYLE @@ -0,0 +1,29 @@ +I like to keep all my code to 80 columns or less. I have plenty of screen real +estate, but enjoy 80 columns so that I can have multiple code windows open side +to side and not be plagued by the ugly auto-wrapping of a text editor. + +If you don't oblige me, I will fix any patch you submit to abide 80 columns. + +Note that this style restriction does not preclude gofmt, but introduces a few +peculiarities. The first is that gofmt will occasionally add spacing (typically +to comments) that ends up going over 80 columns. Either shorten the comment or +put it on its own line. + +The second and more common hiccup is when a function definition extends beyond +80 columns. If one adds line breaks to keep it below 80 columns, gofmt will +indent all subsequent lines in a function definition to the same indentation +level of the function body. This results in a less-than-ideal separation +between function definition and function body. To remedy this, simply add a +line break like so: + + func RestackWindowExtra(xu *xgbutil.XUtil, win xproto.Window, stackMode int, + sibling xproto.Window, source int) error { + + return ClientEvent(xu, win, "_NET_RESTACK_WINDOW", source, int(sibling), + stackMode) + } + +Something similar should also be applied to long 'if' or 'for' conditionals, +although it would probably be preferrable to break up the conditional to +smaller chunks with a few helper variables. + diff --git a/vend/xgb/auth.go b/vend/xgb/auth.go new file mode 100644 index 0000000..ec51d10 --- /dev/null +++ b/vend/xgb/auth.go @@ -0,0 +1,110 @@ +package xgb + +/* +auth.go contains functions to facilitate the parsing of .Xauthority files. + +It is largely unmodified from the original XGB package that I forked. +*/ + +import ( + "encoding/binary" + "errors" + "io" + "os" +) + +// readAuthority reads the X authority file for the DISPLAY. +// If hostname == "" or hostname == "localhost", +// then use the system's hostname (as returned by os.Hostname) instead. +func readAuthority(hostname, display string) ( + name string, data []byte, err error) { + + // b is a scratch buffer to use and should be at least 256 bytes long + // (i.e. it should be able to hold a hostname). + b := make([]byte, 256) + + // As per /usr/include/X11/Xauth.h. + const familyLocal = 256 + const familyWild = 65535 + + if len(hostname) == 0 || hostname == "localhost" { + hostname, err = os.Hostname() + if err != nil { + return "", nil, err + } + } + + fname := os.Getenv("XAUTHORITY") + if len(fname) == 0 { + home := os.Getenv("HOME") + if len(home) == 0 { + err = errors.New("Xauthority not found: $XAUTHORITY, $HOME not set") + return "", nil, err + } + fname = home + "/.Xauthority" + } + + r, err := os.Open(fname) + if err != nil { + return "", nil, err + } + defer r.Close() + + for { + var family uint16 + if err := binary.Read(r, binary.BigEndian, &family); err != nil { + return "", nil, err + } + + addr, err := getString(r, b) + if err != nil { + return "", nil, err + } + + disp, err := getString(r, b) + if err != nil { + return "", nil, err + } + + name0, err := getString(r, b) + if err != nil { + return "", nil, err + } + + data0, err := getBytes(r, b) + if err != nil { + return "", nil, err + } + + addrmatch := (family == familyWild) || + (family == familyLocal && addr == hostname) + dispmatch := (disp == "") || (disp == display) + + if addrmatch && dispmatch { + return name0, data0, nil + } + } + panic("unreachable") +} + +func getBytes(r io.Reader, b []byte) ([]byte, error) { + var n uint16 + if err := binary.Read(r, binary.BigEndian, &n); err != nil { + return nil, err + } else if n > uint16(len(b)) { + return nil, errors.New("bytes too long for buffer") + } + + if _, err := io.ReadFull(r, b[0:n]); err != nil { + return nil, err + } + return b[0:n], nil +} + +func getString(r io.Reader, b []byte) (string, error) { + b, err := getBytes(r, b) + if err != nil { + return "", err + } + return string(b), nil +} diff --git a/vend/xgb/bigreq/bigreq.go b/vend/xgb/bigreq/bigreq.go new file mode 100644 index 0000000..d8a5859 --- /dev/null +++ b/vend/xgb/bigreq/bigreq.go @@ -0,0 +1,152 @@ +// Package bigreq is the X client API for the BIG-REQUESTS extension. +package bigreq + +// This file is automatically generated from bigreq.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the BIG-REQUESTS extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 12, "BIG-REQUESTS").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named BIG-REQUESTS could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["BIG-REQUESTS"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["BIG-REQUESTS"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["BIG-REQUESTS"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["BIG-REQUESTS"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["BIG-REQUESTS"] = make(map[int]xgb.NewErrorFun) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// EnableCookie is a cookie used only for Enable requests. +type EnableCookie struct { + *xgb.Cookie +} + +// Enable sends a checked request. +// If an error occurs, it will be returned with the reply by calling EnableCookie.Reply() +func Enable(c *xgb.Conn) EnableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["BIG-REQUESTS"]; !ok { + panic("Cannot issue request 'Enable' using the uninitialized extension 'BIG-REQUESTS'. bigreq.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(enableRequest(c), cookie) + return EnableCookie{cookie} +} + +// EnableUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func EnableUnchecked(c *xgb.Conn) EnableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["BIG-REQUESTS"]; !ok { + panic("Cannot issue request 'Enable' using the uninitialized extension 'BIG-REQUESTS'. bigreq.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(enableRequest(c), cookie) + return EnableCookie{cookie} +} + +// EnableReply represents the data returned from a Enable request. +type EnableReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MaximumRequestLength uint32 +} + +// Reply blocks and returns the reply data for a Enable request. +func (cook EnableCookie) Reply() (*EnableReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return enableReply(buf), nil +} + +// enableReply reads a byte slice into a EnableReply value. +func enableReply(buf []byte) *EnableReply { + v := new(EnableReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MaximumRequestLength = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for Enable +// enableRequest writes a Enable request to a byte slice. +func enableRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["BIG-REQUESTS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} diff --git a/vend/xgb/composite/composite.go b/vend/xgb/composite/composite.go new file mode 100644 index 0000000..4622cee --- /dev/null +++ b/vend/xgb/composite/composite.go @@ -0,0 +1,721 @@ +// Package composite is the X client API for the Composite extension. +package composite + +// This file is automatically generated from composite.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xfixes" + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the Composite extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 9, "Composite").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named Composite could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["Composite"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["Composite"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["Composite"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["Composite"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["Composite"] = make(map[int]xgb.NewErrorFun) +} + +const ( + RedirectAutomatic = 0 + RedirectManual = 1 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CreateRegionFromBorderClipCookie is a cookie used only for CreateRegionFromBorderClip requests. +type CreateRegionFromBorderClipCookie struct { + *xgb.Cookie +} + +// CreateRegionFromBorderClip sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRegionFromBorderClip(c *xgb.Conn, Region xfixes.Region, Window xproto.Window) CreateRegionFromBorderClipCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'CreateRegionFromBorderClip' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRegionFromBorderClipRequest(c, Region, Window), cookie) + return CreateRegionFromBorderClipCookie{cookie} +} + +// CreateRegionFromBorderClipChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRegionFromBorderClipCookie.Check() +func CreateRegionFromBorderClipChecked(c *xgb.Conn, Region xfixes.Region, Window xproto.Window) CreateRegionFromBorderClipCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'CreateRegionFromBorderClip' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRegionFromBorderClipRequest(c, Region, Window), cookie) + return CreateRegionFromBorderClipCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRegionFromBorderClipCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRegionFromBorderClip +// createRegionFromBorderClipRequest writes a CreateRegionFromBorderClip request to a byte slice. +func createRegionFromBorderClipRequest(c *xgb.Conn, Region xfixes.Region, Window xproto.Window) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetOverlayWindowCookie is a cookie used only for GetOverlayWindow requests. +type GetOverlayWindowCookie struct { + *xgb.Cookie +} + +// GetOverlayWindow sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetOverlayWindowCookie.Reply() +func GetOverlayWindow(c *xgb.Conn, Window xproto.Window) GetOverlayWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'GetOverlayWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getOverlayWindowRequest(c, Window), cookie) + return GetOverlayWindowCookie{cookie} +} + +// GetOverlayWindowUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetOverlayWindowUnchecked(c *xgb.Conn, Window xproto.Window) GetOverlayWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'GetOverlayWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getOverlayWindowRequest(c, Window), cookie) + return GetOverlayWindowCookie{cookie} +} + +// GetOverlayWindowReply represents the data returned from a GetOverlayWindow request. +type GetOverlayWindowReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + OverlayWin xproto.Window + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a GetOverlayWindow request. +func (cook GetOverlayWindowCookie) Reply() (*GetOverlayWindowReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getOverlayWindowReply(buf), nil +} + +// getOverlayWindowReply reads a byte slice into a GetOverlayWindowReply value. +func getOverlayWindowReply(buf []byte) *GetOverlayWindowReply { + v := new(GetOverlayWindowReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.OverlayWin = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for GetOverlayWindow +// getOverlayWindowRequest writes a GetOverlayWindow request to a byte slice. +func getOverlayWindowRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// NameWindowPixmapCookie is a cookie used only for NameWindowPixmap requests. +type NameWindowPixmapCookie struct { + *xgb.Cookie +} + +// NameWindowPixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func NameWindowPixmap(c *xgb.Conn, Window xproto.Window, Pixmap xproto.Pixmap) NameWindowPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'NameWindowPixmap' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(nameWindowPixmapRequest(c, Window, Pixmap), cookie) + return NameWindowPixmapCookie{cookie} +} + +// NameWindowPixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using NameWindowPixmapCookie.Check() +func NameWindowPixmapChecked(c *xgb.Conn, Window xproto.Window, Pixmap xproto.Pixmap) NameWindowPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'NameWindowPixmap' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(nameWindowPixmapRequest(c, Window, Pixmap), cookie) + return NameWindowPixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook NameWindowPixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for NameWindowPixmap +// nameWindowPixmapRequest writes a NameWindowPixmap request to a byte slice. +func nameWindowPixmapRequest(c *xgb.Conn, Window xproto.Window, Pixmap xproto.Pixmap) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Pixmap)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ClientMajorVersion) + b += 4 + + xgb.Put32(buf[b:], ClientMinorVersion) + b += 4 + + return buf +} + +// RedirectSubwindowsCookie is a cookie used only for RedirectSubwindows requests. +type RedirectSubwindowsCookie struct { + *xgb.Cookie +} + +// RedirectSubwindows sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RedirectSubwindows(c *xgb.Conn, Window xproto.Window, Update byte) RedirectSubwindowsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'RedirectSubwindows' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(redirectSubwindowsRequest(c, Window, Update), cookie) + return RedirectSubwindowsCookie{cookie} +} + +// RedirectSubwindowsChecked sends a checked request. +// If an error occurs, it can be retrieved using RedirectSubwindowsCookie.Check() +func RedirectSubwindowsChecked(c *xgb.Conn, Window xproto.Window, Update byte) RedirectSubwindowsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'RedirectSubwindows' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(redirectSubwindowsRequest(c, Window, Update), cookie) + return RedirectSubwindowsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RedirectSubwindowsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RedirectSubwindows +// redirectSubwindowsRequest writes a RedirectSubwindows request to a byte slice. +func redirectSubwindowsRequest(c *xgb.Conn, Window xproto.Window, Update byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + buf[b] = Update + b += 1 + + b += 3 // padding + + return buf +} + +// RedirectWindowCookie is a cookie used only for RedirectWindow requests. +type RedirectWindowCookie struct { + *xgb.Cookie +} + +// RedirectWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RedirectWindow(c *xgb.Conn, Window xproto.Window, Update byte) RedirectWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'RedirectWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(redirectWindowRequest(c, Window, Update), cookie) + return RedirectWindowCookie{cookie} +} + +// RedirectWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using RedirectWindowCookie.Check() +func RedirectWindowChecked(c *xgb.Conn, Window xproto.Window, Update byte) RedirectWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'RedirectWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(redirectWindowRequest(c, Window, Update), cookie) + return RedirectWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RedirectWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RedirectWindow +// redirectWindowRequest writes a RedirectWindow request to a byte slice. +func redirectWindowRequest(c *xgb.Conn, Window xproto.Window, Update byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + buf[b] = Update + b += 1 + + b += 3 // padding + + return buf +} + +// ReleaseOverlayWindowCookie is a cookie used only for ReleaseOverlayWindow requests. +type ReleaseOverlayWindowCookie struct { + *xgb.Cookie +} + +// ReleaseOverlayWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ReleaseOverlayWindow(c *xgb.Conn, Window xproto.Window) ReleaseOverlayWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'ReleaseOverlayWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(releaseOverlayWindowRequest(c, Window), cookie) + return ReleaseOverlayWindowCookie{cookie} +} + +// ReleaseOverlayWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using ReleaseOverlayWindowCookie.Check() +func ReleaseOverlayWindowChecked(c *xgb.Conn, Window xproto.Window) ReleaseOverlayWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'ReleaseOverlayWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(releaseOverlayWindowRequest(c, Window), cookie) + return ReleaseOverlayWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ReleaseOverlayWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ReleaseOverlayWindow +// releaseOverlayWindowRequest writes a ReleaseOverlayWindow request to a byte slice. +func releaseOverlayWindowRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// UnredirectSubwindowsCookie is a cookie used only for UnredirectSubwindows requests. +type UnredirectSubwindowsCookie struct { + *xgb.Cookie +} + +// UnredirectSubwindows sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnredirectSubwindows(c *xgb.Conn, Window xproto.Window, Update byte) UnredirectSubwindowsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'UnredirectSubwindows' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(unredirectSubwindowsRequest(c, Window, Update), cookie) + return UnredirectSubwindowsCookie{cookie} +} + +// UnredirectSubwindowsChecked sends a checked request. +// If an error occurs, it can be retrieved using UnredirectSubwindowsCookie.Check() +func UnredirectSubwindowsChecked(c *xgb.Conn, Window xproto.Window, Update byte) UnredirectSubwindowsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'UnredirectSubwindows' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(unredirectSubwindowsRequest(c, Window, Update), cookie) + return UnredirectSubwindowsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnredirectSubwindowsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnredirectSubwindows +// unredirectSubwindowsRequest writes a UnredirectSubwindows request to a byte slice. +func unredirectSubwindowsRequest(c *xgb.Conn, Window xproto.Window, Update byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + buf[b] = Update + b += 1 + + b += 3 // padding + + return buf +} + +// UnredirectWindowCookie is a cookie used only for UnredirectWindow requests. +type UnredirectWindowCookie struct { + *xgb.Cookie +} + +// UnredirectWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnredirectWindow(c *xgb.Conn, Window xproto.Window, Update byte) UnredirectWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'UnredirectWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(unredirectWindowRequest(c, Window, Update), cookie) + return UnredirectWindowCookie{cookie} +} + +// UnredirectWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using UnredirectWindowCookie.Check() +func UnredirectWindowChecked(c *xgb.Conn, Window xproto.Window, Update byte) UnredirectWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Composite"]; !ok { + panic("Cannot issue request 'UnredirectWindow' using the uninitialized extension 'Composite'. composite.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(unredirectWindowRequest(c, Window, Update), cookie) + return UnredirectWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnredirectWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnredirectWindow +// unredirectWindowRequest writes a UnredirectWindow request to a byte slice. +func unredirectWindowRequest(c *xgb.Conn, Window xproto.Window, Update byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Composite"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + buf[b] = Update + b += 1 + + b += 3 // padding + + return buf +} diff --git a/vend/xgb/conn.go b/vend/xgb/conn.go new file mode 100644 index 0000000..f1b85c0 --- /dev/null +++ b/vend/xgb/conn.go @@ -0,0 +1,186 @@ +package xgb + +/* +conn.go contains a couple of functions that do some real dirty work related +to the initial connection handshake with X. + +This code is largely unmodified from the original XGB package that I forked. +*/ + +import ( + "errors" + "fmt" + "io" + "net" + "os" + "strconv" + "strings" +) + +// connect connects to the X server given in the 'display' string, +// and does all the necessary setup handshaking. +// If 'display' is empty it will be taken from os.Getenv("DISPLAY"). +// Note that you should read and understand the "Connection Setup" of the +// X Protocol Reference Manual before changing this function: +// http://goo.gl/4zGQg +func (c *Conn) connect(display string) error { + err := c.dial(display) + if err != nil { + return err + } + + return c.postConnect() +} + +// connect init from to the net.Conn, +func (c *Conn) connectNet(netConn net.Conn) error { + c.conn = netConn + return c.postConnect() +} + +// do the postConnect action after Conn get it's underly net.Conn +func (c *Conn) postConnect() error { + // Get authentication data + authName, authData, err := readAuthority(c.host, c.display) + noauth := false + if err != nil { + Logger.Printf("Could not get authority info: %v", err) + Logger.Println("Trying connection without authority info...") + authName = "" + authData = []byte{} + noauth = true + } + + // Assume that the authentication protocol is "MIT-MAGIC-COOKIE-1". + if !noauth && (authName != "MIT-MAGIC-COOKIE-1" || len(authData) != 16) { + return errors.New("unsupported auth protocol " + authName) + } + + buf := make([]byte, 12+Pad(len(authName))+Pad(len(authData))) + buf[0] = 0x6c + buf[1] = 0 + Put16(buf[2:], 11) + Put16(buf[4:], 0) + Put16(buf[6:], uint16(len(authName))) + Put16(buf[8:], uint16(len(authData))) + Put16(buf[10:], 0) + copy(buf[12:], []byte(authName)) + copy(buf[12+Pad(len(authName)):], authData) + if _, err = c.conn.Write(buf); err != nil { + return err + } + + head := make([]byte, 8) + if _, err = io.ReadFull(c.conn, head[0:8]); err != nil { + return err + } + code := head[0] + reasonLen := head[1] + major := Get16(head[2:]) + minor := Get16(head[4:]) + dataLen := Get16(head[6:]) + + if major != 11 || minor != 0 { + return fmt.Errorf("x protocol version mismatch: %d.%d", major, minor) + } + + buf = make([]byte, int(dataLen)*4+8, int(dataLen)*4+8) + copy(buf, head) + if _, err = io.ReadFull(c.conn, buf[8:]); err != nil { + return err + } + + if code == 0 { + reason := buf[8 : 8+reasonLen] + return fmt.Errorf("x protocol authentication refused: %s", + string(reason)) + } + + // Unfortunately, it isn't really feasible to read the setup bytes here, + // since the code to do so is in a different package. + // Users must call 'xproto.Setup(X)' to get the setup info. + c.SetupBytes = buf + + // But also read stuff that we *need* to get started. + c.setupResourceIdBase = Get32(buf[12:]) + c.setupResourceIdMask = Get32(buf[16:]) + + return nil +} + +// dial initializes the actual net connection with X. +func (c *Conn) dial(display string) error { + if len(display) == 0 { + display = os.Getenv("DISPLAY") + } + + display0 := display + if len(display) == 0 { + return errors.New("empty display string") + } + + colonIdx := strings.LastIndex(display, ":") + if colonIdx < 0 { + return errors.New("bad display string: " + display0) + } + + var protocol, socket string + + if display[0] == '/' { + socket = display[0:colonIdx] + } else { + slashIdx := strings.LastIndex(display, "/") + if slashIdx >= 0 { + protocol = display[0:slashIdx] + c.host = display[slashIdx+1 : colonIdx] + } else { + c.host = display[0:colonIdx] + } + } + + display = display[colonIdx+1 : len(display)] + if len(display) == 0 { + return errors.New("bad display string: " + display0) + } + + var scr string + dotIdx := strings.LastIndex(display, ".") + if dotIdx < 0 { + c.display = display[0:] + } else { + c.display = display[0:dotIdx] + scr = display[dotIdx+1:] + } + + var err error + c.DisplayNumber, err = strconv.Atoi(c.display) + if err != nil || c.DisplayNumber < 0 { + return errors.New("bad display string: " + display0) + } + + if len(scr) != 0 { + c.DefaultScreen, err = strconv.Atoi(scr) + if err != nil { + return errors.New("bad display string: " + display0) + } + } + + // Connect to server + if len(socket) != 0 { + c.conn, err = net.Dial("unix", socket+":"+c.display) + } else if len(c.host) != 0 && c.host != "unix" { + if protocol == "" { + protocol = "tcp" + } + c.conn, err = net.Dial(protocol, + c.host+":"+strconv.Itoa(6000+c.DisplayNumber)) + } else { + c.host = "" + c.conn, err = net.Dial("unix", "/tmp/.X11-unix/X"+c.display) + } + + if err != nil { + return errors.New("cannot connect to " + display0 + ": " + err.Error()) + } + return nil +} diff --git a/vend/xgb/cookie.go b/vend/xgb/cookie.go new file mode 100644 index 0000000..c012cfd --- /dev/null +++ b/vend/xgb/cookie.go @@ -0,0 +1,178 @@ +package xgb + +import ( + "errors" + "io" +) + +// Cookie is the internal representation of a cookie, where one is generated +// for *every* request sent by XGB. +// 'cookie' is most frequently used by embedding it into a more specific +// kind of cookie, i.e., 'GetInputFocusCookie'. +type Cookie struct { + conn *Conn + Sequence uint16 + replyChan chan []byte + errorChan chan error + pingChan chan bool +} + +// NewCookie creates a new cookie with the correct channels initialized +// depending upon the values of 'checked' and 'reply'. Together, there are +// four different kinds of cookies. (See more detailed comments in the +// function for more info on those.) +// Note that a sequence number is not set until just before the request +// corresponding to this cookie is sent over the wire. +// +// Unless you're building requests from bytes by hand, this method should +// not be used. +func (c *Conn) NewCookie(checked, reply bool) *Cookie { + cookie := &Cookie{ + conn: c, + Sequence: 0, // we add the sequence id just before sending a request + replyChan: nil, + errorChan: nil, + pingChan: nil, + } + + // There are four different kinds of cookies: + // Checked requests with replies get a reply channel and an error channel. + // Unchecked requests with replies get a reply channel and a ping channel. + // Checked requests w/o replies get a ping channel and an error channel. + // Unchecked requests w/o replies get no channels. + // The reply channel is used to send reply data. + // The error channel is used to send error data. + // The ping channel is used when one of the 'reply' or 'error' channels + // is missing but the other is present. The ping channel is way to force + // the blocking to stop and basically say "the error has been received + // in the main event loop" (when the ping channel is coupled with a reply + // channel) or "the request you made that has no reply was successful" + // (when the ping channel is coupled with an error channel). + if checked { + cookie.errorChan = make(chan error, 1) + if !reply { + cookie.pingChan = make(chan bool, 1) + } + } + if reply { + cookie.replyChan = make(chan []byte, 1) + if !checked { + cookie.pingChan = make(chan bool, 1) + } + } + + return cookie +} + +// Reply detects whether this is a checked or unchecked cookie, and calls +// 'replyChecked' or 'replyUnchecked' appropriately. +// +// Unless you're building requests from bytes by hand, this method should +// not be used. +func (c Cookie) Reply() ([]byte, error) { + // checked + if c.errorChan != nil { + return c.replyChecked() + } + return c.replyUnchecked() +} + +// replyChecked waits for a response on either the replyChan or errorChan +// channels. If the former arrives, the bytes are returned with a nil error. +// If the latter arrives, no bytes are returned (nil) and the error received +// is returned. +// Returns (nil, io.EOF) when the connection is closed. +// +// Unless you're building requests from bytes by hand, this method should +// not be used. +func (c Cookie) replyChecked() ([]byte, error) { + if c.replyChan == nil { + return nil, errors.New("Cannot call 'replyChecked' on a cookie that " + + "is not expecting a *reply* or an error.") + } + if c.errorChan == nil { + return nil, errors.New("Cannot call 'replyChecked' on a cookie that " + + "is not expecting a reply or an *error*.") + } + + select { + case reply := <-c.replyChan: + return reply, nil + case err := <-c.errorChan: + return nil, err + case <-c.conn.doneRead: + // c.conn.readResponses is no more, there will be no replys or errors + return nil, io.EOF + } +} + +// replyUnchecked waits for a response on either the replyChan or pingChan +// channels. If the former arrives, the bytes are returned with a nil error. +// If the latter arrives, no bytes are returned (nil) and a nil error +// is returned. (In the latter case, the corresponding error can be retrieved +// from (Wait|Poll)ForEvent asynchronously.) +// Returns (nil, io.EOF) when the connection is closed. +// In all honesty, you *probably* don't want to use this method. +// +// Unless you're building requests from bytes by hand, this method should +// not be used. +func (c Cookie) replyUnchecked() ([]byte, error) { + if c.replyChan == nil { + return nil, errors.New("Cannot call 'replyUnchecked' on a cookie " + + "that is not expecting a *reply*.") + } + + select { + case reply := <-c.replyChan: + return reply, nil + case <-c.pingChan: + return nil, nil + case <-c.conn.doneRead: + // c.conn.readResponses is no more, there will be no replys or pings + return nil, io.EOF + } +} + +// Check is used for checked requests that have no replies. It is a mechanism +// by which to report "success" or "error" in a synchronous fashion. (Therefore, +// unchecked requests without replies cannot use this method.) +// If the request causes an error, it is sent to this cookie's errorChan. +// If the request was successful, there is no response from the server. +// Thus, pingChan is sent a value when the *next* reply is read. +// If no more replies are being processed, we force a round trip request with +// GetInputFocus. +// Returns io.EOF error when the connection is closed. +// +// Unless you're building requests from bytes by hand, this method should +// not be used. +func (c Cookie) Check() error { + if c.replyChan != nil { + return errors.New("Cannot call 'Check' on a cookie that is " + + "expecting a *reply*. Use 'Reply' instead.") + } + if c.errorChan == nil { + return errors.New("Cannot call 'Check' on a cookie that is " + + "not expecting a possible *error*.") + } + + // First do a quick non-blocking check to see if we've been pinged. + select { + case err := <-c.errorChan: + return err + case <-c.pingChan: + return nil + default: + } + + // Now force a round trip and try again, but block this time. + c.conn.Sync() + select { + case err := <-c.errorChan: + return err + case <-c.pingChan: + return nil + case <-c.conn.doneRead: + // c.conn.readResponses is no more, there will be no errors or pings + return io.EOF + } +} diff --git a/vend/xgb/damage/damage.go b/vend/xgb/damage/damage.go new file mode 100644 index 0000000..53326d9 --- /dev/null +++ b/vend/xgb/damage/damage.go @@ -0,0 +1,592 @@ +// Package damage is the X client API for the DAMAGE extension. +package damage + +// This file is automatically generated from damage.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xfixes" + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the DAMAGE extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 6, "DAMAGE").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named DAMAGE could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["DAMAGE"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["DAMAGE"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["DAMAGE"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["DAMAGE"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["DAMAGE"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadDamage is the error number for a BadBadDamage. +const BadBadDamage = 0 + +type BadDamageError struct { + Sequence uint16 + NiceName string +} + +// BadDamageErrorNew constructs a BadDamageError value that implements xgb.Error from a byte slice. +func BadDamageErrorNew(buf []byte) xgb.Error { + v := BadDamageError{} + v.NiceName = "BadDamage" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadDamage error. +// This is mostly used internally. +func (err BadDamageError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadDamage error. If no bad value exists, 0 is returned. +func (err BadDamageError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadDamage error. + +func (err BadDamageError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadDamage {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["DAMAGE"][0] = BadDamageErrorNew +} + +type Damage uint32 + +func NewDamageId(c *xgb.Conn) (Damage, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Damage(id), nil +} + +// Notify is the event number for a NotifyEvent. +const Notify = 0 + +type NotifyEvent struct { + Sequence uint16 + Level byte + Drawable xproto.Drawable + Damage Damage + Timestamp xproto.Timestamp + Area xproto.Rectangle + Geometry xproto.Rectangle +} + +// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice. +func NotifyEventNew(buf []byte) xgb.Event { + v := NotifyEvent{} + b := 1 // don't read event number + + v.Level = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Drawable = xproto.Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.Damage = Damage(xgb.Get32(buf[b:])) + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Area = xproto.Rectangle{} + b += xproto.RectangleRead(buf[b:], &v.Area) + + v.Geometry = xproto.Rectangle{} + b += xproto.RectangleRead(buf[b:], &v.Geometry) + + return v +} + +// Bytes writes a NotifyEvent value to a byte slice. +func (v NotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = v.Level + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Damage)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + { + structBytes := v.Area.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.Geometry.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf +} + +// SequenceId returns the sequence id attached to the Notify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v NotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of NotifyEvent. +func (v NotifyEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Level: %d", v.Level)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("Damage: %d", v.Damage)) + fieldVals = append(fieldVals, xgb.Sprintf("Timestamp: %d", v.Timestamp)) + return "Notify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["DAMAGE"][0] = NotifyEventNew +} + +const ( + ReportLevelRawRectangles = 0 + ReportLevelDeltaRectangles = 1 + ReportLevelBoundingBox = 2 + ReportLevelNonEmpty = 3 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AddCookie is a cookie used only for Add requests. +type AddCookie struct { + *xgb.Cookie +} + +// Add sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Add(c *xgb.Conn, Drawable xproto.Drawable, Region xfixes.Region) AddCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Add' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(addRequest(c, Drawable, Region), cookie) + return AddCookie{cookie} +} + +// AddChecked sends a checked request. +// If an error occurs, it can be retrieved using AddCookie.Check() +func AddChecked(c *xgb.Conn, Drawable xproto.Drawable, Region xfixes.Region) AddCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Add' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(addRequest(c, Drawable, Region), cookie) + return AddCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AddCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Add +// addRequest writes a Add request to a byte slice. +func addRequest(c *xgb.Conn, Drawable xproto.Drawable, Region xfixes.Region) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DAMAGE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + return buf +} + +// CreateCookie is a cookie used only for Create requests. +type CreateCookie struct { + *xgb.Cookie +} + +// Create sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Create(c *xgb.Conn, Damage Damage, Drawable xproto.Drawable, Level byte) CreateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Create' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRequest(c, Damage, Drawable, Level), cookie) + return CreateCookie{cookie} +} + +// CreateChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateCookie.Check() +func CreateChecked(c *xgb.Conn, Damage Damage, Drawable xproto.Drawable, Level byte) CreateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Create' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRequest(c, Damage, Drawable, Level), cookie) + return CreateCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Create +// createRequest writes a Create request to a byte slice. +func createRequest(c *xgb.Conn, Damage Damage, Drawable xproto.Drawable, Level byte) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DAMAGE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Damage)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + buf[b] = Level + b += 1 + + b += 3 // padding + + return buf +} + +// DestroyCookie is a cookie used only for Destroy requests. +type DestroyCookie struct { + *xgb.Cookie +} + +// Destroy sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Destroy(c *xgb.Conn, Damage Damage) DestroyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Destroy' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyRequest(c, Damage), cookie) + return DestroyCookie{cookie} +} + +// DestroyChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyCookie.Check() +func DestroyChecked(c *xgb.Conn, Damage Damage) DestroyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Destroy' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyRequest(c, Damage), cookie) + return DestroyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Destroy +// destroyRequest writes a Destroy request to a byte slice. +func destroyRequest(c *xgb.Conn, Damage Damage) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DAMAGE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Damage)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DAMAGE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ClientMajorVersion) + b += 4 + + xgb.Put32(buf[b:], ClientMinorVersion) + b += 4 + + return buf +} + +// SubtractCookie is a cookie used only for Subtract requests. +type SubtractCookie struct { + *xgb.Cookie +} + +// Subtract sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Subtract(c *xgb.Conn, Damage Damage, Repair xfixes.Region, Parts xfixes.Region) SubtractCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Subtract' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(subtractRequest(c, Damage, Repair, Parts), cookie) + return SubtractCookie{cookie} +} + +// SubtractChecked sends a checked request. +// If an error occurs, it can be retrieved using SubtractCookie.Check() +func SubtractChecked(c *xgb.Conn, Damage Damage, Repair xfixes.Region, Parts xfixes.Region) SubtractCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DAMAGE"]; !ok { + panic("Cannot issue request 'Subtract' using the uninitialized extension 'DAMAGE'. damage.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(subtractRequest(c, Damage, Repair, Parts), cookie) + return SubtractCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SubtractCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Subtract +// subtractRequest writes a Subtract request to a byte slice. +func subtractRequest(c *xgb.Conn, Damage Damage, Repair xfixes.Region, Parts xfixes.Region) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DAMAGE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Damage)) + b += 4 + + xgb.Put32(buf[b:], uint32(Repair)) + b += 4 + + xgb.Put32(buf[b:], uint32(Parts)) + b += 4 + + return buf +} diff --git a/vend/xgb/doc.go b/vend/xgb/doc.go new file mode 100644 index 0000000..3a28558 --- /dev/null +++ b/vend/xgb/doc.go @@ -0,0 +1,146 @@ +/* +Package XGB provides the X Go Binding, which is a low-level API to communicate +with the core X protocol and many of the X extensions. + +It is *very* closely modeled on XCB, so that experience with XCB (or xpyb) is +easily translatable to XGB. That is, it uses the same cookie/reply model +and is thread safe. There are otherwise no major differences (in the API). + +Most uses of XGB typically fall under the realm of window manager and GUI kit +development, but other applications (like pagers, panels, tilers, etc.) may +also require XGB. Moreover, it is a near certainty that if you need to work +with X, xgbutil will be of great use to you as well: +https://github.com/jezek/xgbutil + +Example + +This is an extremely terse example that demonstrates how to connect to X, +create a window, listen to StructureNotify events and Key{Press,Release} +events, map the window, and print out all events received. An example with +accompanying documentation can be found in examples/create-window. + + package main + + import ( + "fmt" + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" + ) + + func main() { + X, err := xgb.NewConn() + if err != nil { + fmt.Println(err) + return + } + + wid, _ := xproto.NewWindowId(X) + screen := xproto.Setup(X).DefaultScreen(X) + xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root, + 0, 0, 500, 500, 0, + xproto.WindowClassInputOutput, screen.RootVisual, + xproto.CwBackPixel | xproto.CwEventMask, + []uint32{ // values must be in the order defined by the protocol + 0xffffffff, + xproto.EventMaskStructureNotify | + xproto.EventMaskKeyPress | + xproto.EventMaskKeyRelease}) + + xproto.MapWindow(X, wid) + for { + ev, xerr := X.WaitForEvent() + if ev == nil && xerr == nil { + fmt.Println("Both event and error are nil. Exiting...") + return + } + + if ev != nil { + fmt.Printf("Event: %s\n", ev) + } + if xerr != nil { + fmt.Printf("Error: %s\n", xerr) + } + } + } + +Xinerama Example + +This is another small example that shows how to query Xinerama for geometry +information of each active head. Accompanying documentation for this example +can be found in examples/xinerama. + + package main + + import ( + "fmt" + "log" + "github.com/jezek/xgb" + "github.com/jezek/xgb/xinerama" + ) + + func main() { + X, err := xgb.NewConn() + if err != nil { + log.Fatal(err) + } + + // Initialize the Xinerama extension. + // The appropriate 'Init' function must be run for *every* + // extension before any of its requests can be used. + err = xinerama.Init(X) + if err != nil { + log.Fatal(err) + } + + reply, err := xinerama.QueryScreens(X).Reply() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Number of heads: %d\n", reply.Number) + for i, screen := range reply.ScreenInfo { + fmt.Printf("%d :: X: %d, Y: %d, Width: %d, Height: %d\n", + i, screen.XOrg, screen.YOrg, screen.Width, screen.Height) + } + } + +Parallelism + +XGB can benefit greatly from parallelism due to its concurrent design. For +evidence of this claim, please see the benchmarks in xproto/xproto_test.go. + +Tests + +xproto/xproto_test.go contains a number of contrived tests that stress +particular corners of XGB that I presume could be problem areas. Namely: +requests with no replies, requests with replies, checked errors, unchecked +errors, sequence number wrapping, cookie buffer flushing (i.e., forcing a round +trip every N requests made that don't have a reply), getting/setting properties +and creating a window and listening to StructureNotify events. + +Code Generator + +Both XCB and xpyb use the same Python module (xcbgen) for a code generator. XGB +(before this fork) used the same code generator as well, but in my attempt to +add support for more extensions, I found the code generator extremely difficult +to work with. Therefore, I re-wrote the code generator in Go. It can be found +in its own sub-package, xgbgen, of xgb. My design of xgbgen includes a rough +consideration that it could be used for other languages. + +What works + +I am reasonably confident that the core X protocol is in full working form. I've +also tested the Xinerama and RandR extensions sparingly. Many of the other +existing extensions have Go source generated (and are compilable) and are +included in this package, but I am currently unsure of their status. They +*should* work. + +What does not work + +XKB is the only extension that intentionally does not work, although I suspect +that GLX also does not work (however, there is Go source code for GLX that +compiles, unlike XKB). I don't currently have any intention of getting XKB +working, due to its complexity and my current mental incapacity to test it. + +*/ +package xgb diff --git a/vend/xgb/dpms/dpms.go b/vend/xgb/dpms/dpms.go new file mode 100644 index 0000000..da28f1e --- /dev/null +++ b/vend/xgb/dpms/dpms.go @@ -0,0 +1,715 @@ +// Package dpms is the X client API for the DPMS extension. +package dpms + +// This file is automatically generated from dpms.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the DPMS extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 4, "DPMS").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named DPMS could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["DPMS"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["DPMS"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["DPMS"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["DPMS"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["DPMS"] = make(map[int]xgb.NewErrorFun) +} + +const ( + DPMSModeOn = 0 + DPMSModeStandby = 1 + DPMSModeSuspend = 2 + DPMSModeOff = 3 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CapableCookie is a cookie used only for Capable requests. +type CapableCookie struct { + *xgb.Cookie +} + +// Capable sends a checked request. +// If an error occurs, it will be returned with the reply by calling CapableCookie.Reply() +func Capable(c *xgb.Conn) CapableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Capable' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(capableRequest(c), cookie) + return CapableCookie{cookie} +} + +// CapableUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CapableUnchecked(c *xgb.Conn) CapableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Capable' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(capableRequest(c), cookie) + return CapableCookie{cookie} +} + +// CapableReply represents the data returned from a Capable request. +type CapableReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Capable bool + // padding: 23 bytes +} + +// Reply blocks and returns the reply data for a Capable request. +func (cook CapableCookie) Reply() (*CapableReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return capableReply(buf), nil +} + +// capableReply reads a byte slice into a CapableReply value. +func capableReply(buf []byte) *CapableReply { + v := new(CapableReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.Capable = true + } else { + v.Capable = false + } + b += 1 + + b += 23 // padding + + return v +} + +// Write request to wire for Capable +// capableRequest writes a Capable request to a byte slice. +func capableRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// DisableCookie is a cookie used only for Disable requests. +type DisableCookie struct { + *xgb.Cookie +} + +// Disable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Disable(c *xgb.Conn) DisableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Disable' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(disableRequest(c), cookie) + return DisableCookie{cookie} +} + +// DisableChecked sends a checked request. +// If an error occurs, it can be retrieved using DisableCookie.Check() +func DisableChecked(c *xgb.Conn) DisableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Disable' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(disableRequest(c), cookie) + return DisableCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DisableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Disable +// disableRequest writes a Disable request to a byte slice. +func disableRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// EnableCookie is a cookie used only for Enable requests. +type EnableCookie struct { + *xgb.Cookie +} + +// Enable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Enable(c *xgb.Conn) EnableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Enable' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(enableRequest(c), cookie) + return EnableCookie{cookie} +} + +// EnableChecked sends a checked request. +// If an error occurs, it can be retrieved using EnableCookie.Check() +func EnableChecked(c *xgb.Conn) EnableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Enable' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(enableRequest(c), cookie) + return EnableCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook EnableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Enable +// enableRequest writes a Enable request to a byte slice. +func enableRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// ForceLevelCookie is a cookie used only for ForceLevel requests. +type ForceLevelCookie struct { + *xgb.Cookie +} + +// ForceLevel sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ForceLevel(c *xgb.Conn, PowerLevel uint16) ForceLevelCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'ForceLevel' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(forceLevelRequest(c, PowerLevel), cookie) + return ForceLevelCookie{cookie} +} + +// ForceLevelChecked sends a checked request. +// If an error occurs, it can be retrieved using ForceLevelCookie.Check() +func ForceLevelChecked(c *xgb.Conn, PowerLevel uint16) ForceLevelCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'ForceLevel' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(forceLevelRequest(c, PowerLevel), cookie) + return ForceLevelCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ForceLevelCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ForceLevel +// forceLevelRequest writes a ForceLevel request to a byte slice. +func forceLevelRequest(c *xgb.Conn, PowerLevel uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], PowerLevel) + b += 2 + + return buf +} + +// GetTimeoutsCookie is a cookie used only for GetTimeouts requests. +type GetTimeoutsCookie struct { + *xgb.Cookie +} + +// GetTimeouts sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTimeoutsCookie.Reply() +func GetTimeouts(c *xgb.Conn) GetTimeoutsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'GetTimeouts' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTimeoutsRequest(c), cookie) + return GetTimeoutsCookie{cookie} +} + +// GetTimeoutsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTimeoutsUnchecked(c *xgb.Conn) GetTimeoutsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'GetTimeouts' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTimeoutsRequest(c), cookie) + return GetTimeoutsCookie{cookie} +} + +// GetTimeoutsReply represents the data returned from a GetTimeouts request. +type GetTimeoutsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + StandbyTimeout uint16 + SuspendTimeout uint16 + OffTimeout uint16 + // padding: 18 bytes +} + +// Reply blocks and returns the reply data for a GetTimeouts request. +func (cook GetTimeoutsCookie) Reply() (*GetTimeoutsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTimeoutsReply(buf), nil +} + +// getTimeoutsReply reads a byte slice into a GetTimeoutsReply value. +func getTimeoutsReply(buf []byte) *GetTimeoutsReply { + v := new(GetTimeoutsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.StandbyTimeout = xgb.Get16(buf[b:]) + b += 2 + + v.SuspendTimeout = xgb.Get16(buf[b:]) + b += 2 + + v.OffTimeout = xgb.Get16(buf[b:]) + b += 2 + + b += 18 // padding + + return v +} + +// Write request to wire for GetTimeouts +// getTimeoutsRequest writes a GetTimeouts request to a byte slice. +func getTimeoutsRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetVersionCookie is a cookie used only for GetVersion requests. +type GetVersionCookie struct { + *xgb.Cookie +} + +// GetVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetVersionCookie.Reply() +func GetVersion(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) GetVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'GetVersion' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return GetVersionCookie{cookie} +} + +// GetVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) GetVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'GetVersion' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return GetVersionCookie{cookie} +} + +// GetVersionReply represents the data returned from a GetVersion request. +type GetVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ServerMajorVersion uint16 + ServerMinorVersion uint16 +} + +// Reply blocks and returns the reply data for a GetVersion request. +func (cook GetVersionCookie) Reply() (*GetVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getVersionReply(buf), nil +} + +// getVersionReply reads a byte slice into a GetVersionReply value. +func getVersionReply(buf []byte) *GetVersionReply { + v := new(GetVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ServerMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ServerMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for GetVersion +// getVersionRequest writes a GetVersion request to a byte slice. +func getVersionRequest(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], ClientMajorVersion) + b += 2 + + xgb.Put16(buf[b:], ClientMinorVersion) + b += 2 + + return buf +} + +// InfoCookie is a cookie used only for Info requests. +type InfoCookie struct { + *xgb.Cookie +} + +// Info sends a checked request. +// If an error occurs, it will be returned with the reply by calling InfoCookie.Reply() +func Info(c *xgb.Conn) InfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Info' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(infoRequest(c), cookie) + return InfoCookie{cookie} +} + +// InfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func InfoUnchecked(c *xgb.Conn) InfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'Info' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(infoRequest(c), cookie) + return InfoCookie{cookie} +} + +// InfoReply represents the data returned from a Info request. +type InfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + PowerLevel uint16 + State bool + // padding: 21 bytes +} + +// Reply blocks and returns the reply data for a Info request. +func (cook InfoCookie) Reply() (*InfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return infoReply(buf), nil +} + +// infoReply reads a byte slice into a InfoReply value. +func infoReply(buf []byte) *InfoReply { + v := new(InfoReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PowerLevel = xgb.Get16(buf[b:]) + b += 2 + + if buf[b] == 1 { + v.State = true + } else { + v.State = false + } + b += 1 + + b += 21 // padding + + return v +} + +// Write request to wire for Info +// infoRequest writes a Info request to a byte slice. +func infoRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// SetTimeoutsCookie is a cookie used only for SetTimeouts requests. +type SetTimeoutsCookie struct { + *xgb.Cookie +} + +// SetTimeouts sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetTimeouts(c *xgb.Conn, StandbyTimeout uint16, SuspendTimeout uint16, OffTimeout uint16) SetTimeoutsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'SetTimeouts' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setTimeoutsRequest(c, StandbyTimeout, SuspendTimeout, OffTimeout), cookie) + return SetTimeoutsCookie{cookie} +} + +// SetTimeoutsChecked sends a checked request. +// If an error occurs, it can be retrieved using SetTimeoutsCookie.Check() +func SetTimeoutsChecked(c *xgb.Conn, StandbyTimeout uint16, SuspendTimeout uint16, OffTimeout uint16) SetTimeoutsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DPMS"]; !ok { + panic("Cannot issue request 'SetTimeouts' using the uninitialized extension 'DPMS'. dpms.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setTimeoutsRequest(c, StandbyTimeout, SuspendTimeout, OffTimeout), cookie) + return SetTimeoutsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetTimeoutsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetTimeouts +// setTimeoutsRequest writes a SetTimeouts request to a byte slice. +func setTimeoutsRequest(c *xgb.Conn, StandbyTimeout uint16, SuspendTimeout uint16, OffTimeout uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DPMS"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], StandbyTimeout) + b += 2 + + xgb.Put16(buf[b:], SuspendTimeout) + b += 2 + + xgb.Put16(buf[b:], OffTimeout) + b += 2 + + return buf +} diff --git a/vend/xgb/dri2/dri2.go b/vend/xgb/dri2/dri2.go new file mode 100644 index 0000000..1cc1d0a --- /dev/null +++ b/vend/xgb/dri2/dri2.go @@ -0,0 +1,1821 @@ +// Package dri2 is the X client API for the DRI2 extension. +package dri2 + +// This file is automatically generated from dri2.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the DRI2 extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 4, "DRI2").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named DRI2 could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["DRI2"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["DRI2"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["DRI2"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["DRI2"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["DRI2"] = make(map[int]xgb.NewErrorFun) +} + +type AttachFormat struct { + Attachment uint32 + Format uint32 +} + +// AttachFormatRead reads a byte slice into a AttachFormat value. +func AttachFormatRead(buf []byte, v *AttachFormat) int { + b := 0 + + v.Attachment = xgb.Get32(buf[b:]) + b += 4 + + v.Format = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// AttachFormatReadList reads a byte slice into a list of AttachFormat values. +func AttachFormatReadList(buf []byte, dest []AttachFormat) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = AttachFormat{} + b += AttachFormatRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a AttachFormat value to a byte slice. +func (v AttachFormat) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], v.Attachment) + b += 4 + + xgb.Put32(buf[b:], v.Format) + b += 4 + + return buf[:b] +} + +// AttachFormatListBytes writes a list of AttachFormat values to a byte slice. +func AttachFormatListBytes(buf []byte, list []AttachFormat) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + AttachmentBufferFrontLeft = 0 + AttachmentBufferBackLeft = 1 + AttachmentBufferFrontRight = 2 + AttachmentBufferBackRight = 3 + AttachmentBufferDepth = 4 + AttachmentBufferStencil = 5 + AttachmentBufferAccum = 6 + AttachmentBufferFakeFrontLeft = 7 + AttachmentBufferFakeFrontRight = 8 + AttachmentBufferDepthStencil = 9 + AttachmentBufferHiz = 10 +) + +// BufferSwapComplete is the event number for a BufferSwapCompleteEvent. +const BufferSwapComplete = 0 + +type BufferSwapCompleteEvent struct { + Sequence uint16 + // padding: 1 bytes + EventType uint16 + // padding: 2 bytes + Drawable xproto.Drawable + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + Sbc uint32 +} + +// BufferSwapCompleteEventNew constructs a BufferSwapCompleteEvent value that implements xgb.Event from a byte slice. +func BufferSwapCompleteEventNew(buf []byte) xgb.Event { + v := BufferSwapCompleteEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.EventType = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Drawable = xproto.Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.Sbc = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Bytes writes a BufferSwapCompleteEvent value to a byte slice. +func (v BufferSwapCompleteEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put16(buf[b:], v.EventType) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put32(buf[b:], v.UstHi) + b += 4 + + xgb.Put32(buf[b:], v.UstLo) + b += 4 + + xgb.Put32(buf[b:], v.MscHi) + b += 4 + + xgb.Put32(buf[b:], v.MscLo) + b += 4 + + xgb.Put32(buf[b:], v.Sbc) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the BufferSwapComplete event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v BufferSwapCompleteEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of BufferSwapCompleteEvent. +func (v BufferSwapCompleteEvent) String() string { + fieldVals := make([]string, 0, 9) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("EventType: %d", v.EventType)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("UstHi: %d", v.UstHi)) + fieldVals = append(fieldVals, xgb.Sprintf("UstLo: %d", v.UstLo)) + fieldVals = append(fieldVals, xgb.Sprintf("MscHi: %d", v.MscHi)) + fieldVals = append(fieldVals, xgb.Sprintf("MscLo: %d", v.MscLo)) + fieldVals = append(fieldVals, xgb.Sprintf("Sbc: %d", v.Sbc)) + return "BufferSwapComplete {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["DRI2"][0] = BufferSwapCompleteEventNew +} + +type DRI2Buffer struct { + Attachment uint32 + Name uint32 + Pitch uint32 + Cpp uint32 + Flags uint32 +} + +// DRI2BufferRead reads a byte slice into a DRI2Buffer value. +func DRI2BufferRead(buf []byte, v *DRI2Buffer) int { + b := 0 + + v.Attachment = xgb.Get32(buf[b:]) + b += 4 + + v.Name = xgb.Get32(buf[b:]) + b += 4 + + v.Pitch = xgb.Get32(buf[b:]) + b += 4 + + v.Cpp = xgb.Get32(buf[b:]) + b += 4 + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// DRI2BufferReadList reads a byte slice into a list of DRI2Buffer values. +func DRI2BufferReadList(buf []byte, dest []DRI2Buffer) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = DRI2Buffer{} + b += DRI2BufferRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a DRI2Buffer value to a byte slice. +func (v DRI2Buffer) Bytes() []byte { + buf := make([]byte, 20) + b := 0 + + xgb.Put32(buf[b:], v.Attachment) + b += 4 + + xgb.Put32(buf[b:], v.Name) + b += 4 + + xgb.Put32(buf[b:], v.Pitch) + b += 4 + + xgb.Put32(buf[b:], v.Cpp) + b += 4 + + xgb.Put32(buf[b:], v.Flags) + b += 4 + + return buf[:b] +} + +// DRI2BufferListBytes writes a list of DRI2Buffer values to a byte slice. +func DRI2BufferListBytes(buf []byte, list []DRI2Buffer) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + DriverTypeDri = 0 + DriverTypeVdpau = 1 +) + +const ( + EventTypeExchangeComplete = 1 + EventTypeBlitComplete = 2 + EventTypeFlipComplete = 3 +) + +// InvalidateBuffers is the event number for a InvalidateBuffersEvent. +const InvalidateBuffers = 1 + +type InvalidateBuffersEvent struct { + Sequence uint16 + // padding: 1 bytes + Drawable xproto.Drawable +} + +// InvalidateBuffersEventNew constructs a InvalidateBuffersEvent value that implements xgb.Event from a byte slice. +func InvalidateBuffersEventNew(buf []byte) xgb.Event { + v := InvalidateBuffersEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Drawable = xproto.Drawable(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a InvalidateBuffersEvent value to a byte slice. +func (v InvalidateBuffersEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 1 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the InvalidateBuffers event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v InvalidateBuffersEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of InvalidateBuffersEvent. +func (v InvalidateBuffersEvent) String() string { + fieldVals := make([]string, 0, 2) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + return "InvalidateBuffers {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["DRI2"][1] = InvalidateBuffersEventNew +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AuthenticateCookie is a cookie used only for Authenticate requests. +type AuthenticateCookie struct { + *xgb.Cookie +} + +// Authenticate sends a checked request. +// If an error occurs, it will be returned with the reply by calling AuthenticateCookie.Reply() +func Authenticate(c *xgb.Conn, Window xproto.Window, Magic uint32) AuthenticateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Authenticate' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(authenticateRequest(c, Window, Magic), cookie) + return AuthenticateCookie{cookie} +} + +// AuthenticateUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AuthenticateUnchecked(c *xgb.Conn, Window xproto.Window, Magic uint32) AuthenticateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Authenticate' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(authenticateRequest(c, Window, Magic), cookie) + return AuthenticateCookie{cookie} +} + +// AuthenticateReply represents the data returned from a Authenticate request. +type AuthenticateReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Authenticated uint32 +} + +// Reply blocks and returns the reply data for a Authenticate request. +func (cook AuthenticateCookie) Reply() (*AuthenticateReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return authenticateReply(buf), nil +} + +// authenticateReply reads a byte slice into a AuthenticateReply value. +func authenticateReply(buf []byte) *AuthenticateReply { + v := new(AuthenticateReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Authenticated = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for Authenticate +// authenticateRequest writes a Authenticate request to a byte slice. +func authenticateRequest(c *xgb.Conn, Window xproto.Window, Magic uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], Magic) + b += 4 + + return buf +} + +// ConnectCookie is a cookie used only for Connect requests. +type ConnectCookie struct { + *xgb.Cookie +} + +// Connect sends a checked request. +// If an error occurs, it will be returned with the reply by calling ConnectCookie.Reply() +func Connect(c *xgb.Conn, Window xproto.Window, DriverType uint32) ConnectCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Connect' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(connectRequest(c, Window, DriverType), cookie) + return ConnectCookie{cookie} +} + +// ConnectUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ConnectUnchecked(c *xgb.Conn, Window xproto.Window, DriverType uint32) ConnectCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Connect' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(connectRequest(c, Window, DriverType), cookie) + return ConnectCookie{cookie} +} + +// ConnectReply represents the data returned from a Connect request. +type ConnectReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + DriverNameLength uint32 + DeviceNameLength uint32 + // padding: 16 bytes + DriverName string // size: xgb.Pad((int(DriverNameLength) * 1)) + AlignmentPad []byte // size: xgb.Pad(((((int(DriverNameLength) + 3) & -4) - int(DriverNameLength)) * 1)) + DeviceName string // size: xgb.Pad((int(DeviceNameLength) * 1)) +} + +// Reply blocks and returns the reply data for a Connect request. +func (cook ConnectCookie) Reply() (*ConnectReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return connectReply(buf), nil +} + +// connectReply reads a byte slice into a ConnectReply value. +func connectReply(buf []byte) *ConnectReply { + v := new(ConnectReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.DriverNameLength = xgb.Get32(buf[b:]) + b += 4 + + v.DeviceNameLength = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + { + byteString := make([]byte, v.DriverNameLength) + copy(byteString[:v.DriverNameLength], buf[b:]) + v.DriverName = string(byteString) + b += int(v.DriverNameLength) + } + + v.AlignmentPad = make([]byte, (((int(v.DriverNameLength) + 3) & -4) - int(v.DriverNameLength))) + copy(v.AlignmentPad[:(((int(v.DriverNameLength)+3)&-4)-int(v.DriverNameLength))], buf[b:]) + b += int((((int(v.DriverNameLength) + 3) & -4) - int(v.DriverNameLength))) + + { + byteString := make([]byte, v.DeviceNameLength) + copy(byteString[:v.DeviceNameLength], buf[b:]) + v.DeviceName = string(byteString) + b += int(v.DeviceNameLength) + } + + return v +} + +// Write request to wire for Connect +// connectRequest writes a Connect request to a byte slice. +func connectRequest(c *xgb.Conn, Window xproto.Window, DriverType uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], DriverType) + b += 4 + + return buf +} + +// CopyRegionCookie is a cookie used only for CopyRegion requests. +type CopyRegionCookie struct { + *xgb.Cookie +} + +// CopyRegion sends a checked request. +// If an error occurs, it will be returned with the reply by calling CopyRegionCookie.Reply() +func CopyRegion(c *xgb.Conn, Drawable xproto.Drawable, Region uint32, Dest uint32, Src uint32) CopyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CopyRegion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(copyRegionRequest(c, Drawable, Region, Dest, Src), cookie) + return CopyRegionCookie{cookie} +} + +// CopyRegionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyRegionUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Region uint32, Dest uint32, Src uint32) CopyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CopyRegion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(copyRegionRequest(c, Drawable, Region, Dest, Src), cookie) + return CopyRegionCookie{cookie} +} + +// CopyRegionReply represents the data returned from a CopyRegion request. +type CopyRegionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes +} + +// Reply blocks and returns the reply data for a CopyRegion request. +func (cook CopyRegionCookie) Reply() (*CopyRegionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return copyRegionReply(buf), nil +} + +// copyRegionReply reads a byte slice into a CopyRegionReply value. +func copyRegionReply(buf []byte) *CopyRegionReply { + v := new(CopyRegionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for CopyRegion +// copyRegionRequest writes a CopyRegion request to a byte slice. +func copyRegionRequest(c *xgb.Conn, Drawable xproto.Drawable, Region uint32, Dest uint32, Src uint32) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Region) + b += 4 + + xgb.Put32(buf[b:], Dest) + b += 4 + + xgb.Put32(buf[b:], Src) + b += 4 + + return buf +} + +// CreateDrawableCookie is a cookie used only for CreateDrawable requests. +type CreateDrawableCookie struct { + *xgb.Cookie +} + +// CreateDrawable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateDrawable(c *xgb.Conn, Drawable xproto.Drawable) CreateDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CreateDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createDrawableRequest(c, Drawable), cookie) + return CreateDrawableCookie{cookie} +} + +// CreateDrawableChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateDrawableCookie.Check() +func CreateDrawableChecked(c *xgb.Conn, Drawable xproto.Drawable) CreateDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CreateDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createDrawableRequest(c, Drawable), cookie) + return CreateDrawableCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateDrawableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateDrawable +// createDrawableRequest writes a CreateDrawable request to a byte slice. +func createDrawableRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// DestroyDrawableCookie is a cookie used only for DestroyDrawable requests. +type DestroyDrawableCookie struct { + *xgb.Cookie +} + +// DestroyDrawable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyDrawable(c *xgb.Conn, Drawable xproto.Drawable) DestroyDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'DestroyDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyDrawableRequest(c, Drawable), cookie) + return DestroyDrawableCookie{cookie} +} + +// DestroyDrawableChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyDrawableCookie.Check() +func DestroyDrawableChecked(c *xgb.Conn, Drawable xproto.Drawable) DestroyDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'DestroyDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyDrawableRequest(c, Drawable), cookie) + return DestroyDrawableCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyDrawableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyDrawable +// destroyDrawableRequest writes a DestroyDrawable request to a byte slice. +func destroyDrawableRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// GetBuffersCookie is a cookie used only for GetBuffers requests. +type GetBuffersCookie struct { + *xgb.Cookie +} + +// GetBuffers sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetBuffersCookie.Reply() +func GetBuffers(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []uint32) GetBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getBuffersRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersCookie{cookie} +} + +// GetBuffersUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetBuffersUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []uint32) GetBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getBuffersRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersCookie{cookie} +} + +// GetBuffersReply represents the data returned from a GetBuffers request. +type GetBuffersReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint32 + Height uint32 + Count uint32 + // padding: 12 bytes + Buffers []DRI2Buffer // size: xgb.Pad((int(Count) * 20)) +} + +// Reply blocks and returns the reply data for a GetBuffers request. +func (cook GetBuffersCookie) Reply() (*GetBuffersReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getBuffersReply(buf), nil +} + +// getBuffersReply reads a byte slice into a GetBuffersReply value. +func getBuffersReply(buf []byte) *GetBuffersReply { + v := new(GetBuffersReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Width = xgb.Get32(buf[b:]) + b += 4 + + v.Height = xgb.Get32(buf[b:]) + b += 4 + + v.Count = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Buffers = make([]DRI2Buffer, v.Count) + b += DRI2BufferReadList(buf[b:], v.Buffers) + + return v +} + +// Write request to wire for GetBuffers +// getBuffersRequest writes a GetBuffers request to a byte slice. +func getBuffersRequest(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Attachments) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Count) + b += 4 + + for i := 0; i < int(len(Attachments)); i++ { + xgb.Put32(buf[b:], Attachments[i]) + b += 4 + } + + return buf +} + +// GetBuffersWithFormatCookie is a cookie used only for GetBuffersWithFormat requests. +type GetBuffersWithFormatCookie struct { + *xgb.Cookie +} + +// GetBuffersWithFormat sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetBuffersWithFormatCookie.Reply() +func GetBuffersWithFormat(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []AttachFormat) GetBuffersWithFormatCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffersWithFormat' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getBuffersWithFormatRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersWithFormatCookie{cookie} +} + +// GetBuffersWithFormatUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetBuffersWithFormatUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []AttachFormat) GetBuffersWithFormatCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffersWithFormat' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getBuffersWithFormatRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersWithFormatCookie{cookie} +} + +// GetBuffersWithFormatReply represents the data returned from a GetBuffersWithFormat request. +type GetBuffersWithFormatReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint32 + Height uint32 + Count uint32 + // padding: 12 bytes + Buffers []DRI2Buffer // size: xgb.Pad((int(Count) * 20)) +} + +// Reply blocks and returns the reply data for a GetBuffersWithFormat request. +func (cook GetBuffersWithFormatCookie) Reply() (*GetBuffersWithFormatReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getBuffersWithFormatReply(buf), nil +} + +// getBuffersWithFormatReply reads a byte slice into a GetBuffersWithFormatReply value. +func getBuffersWithFormatReply(buf []byte) *GetBuffersWithFormatReply { + v := new(GetBuffersWithFormatReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Width = xgb.Get32(buf[b:]) + b += 4 + + v.Height = xgb.Get32(buf[b:]) + b += 4 + + v.Count = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Buffers = make([]DRI2Buffer, v.Count) + b += DRI2BufferReadList(buf[b:], v.Buffers) + + return v +} + +// Write request to wire for GetBuffersWithFormat +// getBuffersWithFormatRequest writes a GetBuffersWithFormat request to a byte slice. +func getBuffersWithFormatRequest(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []AttachFormat) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Attachments) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Count) + b += 4 + + b += AttachFormatListBytes(buf[b:], Attachments) + + return buf +} + +// GetMSCCookie is a cookie used only for GetMSC requests. +type GetMSCCookie struct { + *xgb.Cookie +} + +// GetMSC sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMSCCookie.Reply() +func GetMSC(c *xgb.Conn, Drawable xproto.Drawable) GetMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMSCRequest(c, Drawable), cookie) + return GetMSCCookie{cookie} +} + +// GetMSCUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMSCUnchecked(c *xgb.Conn, Drawable xproto.Drawable) GetMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMSCRequest(c, Drawable), cookie) + return GetMSCCookie{cookie} +} + +// GetMSCReply represents the data returned from a GetMSC request. +type GetMSCReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + SbcHi uint32 + SbcLo uint32 +} + +// Reply blocks and returns the reply data for a GetMSC request. +func (cook GetMSCCookie) Reply() (*GetMSCReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMSCReply(buf), nil +} + +// getMSCReply reads a byte slice into a GetMSCReply value. +func getMSCReply(buf []byte) *GetMSCReply { + v := new(GetMSCReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.SbcHi = xgb.Get32(buf[b:]) + b += 4 + + v.SbcLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetMSC +// getMSCRequest writes a GetMSC request to a byte slice. +func getMSCRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// GetParamCookie is a cookie used only for GetParam requests. +type GetParamCookie struct { + *xgb.Cookie +} + +// GetParam sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetParamCookie.Reply() +func GetParam(c *xgb.Conn, Drawable xproto.Drawable, Param uint32) GetParamCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetParam' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getParamRequest(c, Drawable, Param), cookie) + return GetParamCookie{cookie} +} + +// GetParamUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetParamUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Param uint32) GetParamCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetParam' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getParamRequest(c, Drawable, Param), cookie) + return GetParamCookie{cookie} +} + +// GetParamReply represents the data returned from a GetParam request. +type GetParamReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + IsParamRecognized bool + ValueHi uint32 + ValueLo uint32 +} + +// Reply blocks and returns the reply data for a GetParam request. +func (cook GetParamCookie) Reply() (*GetParamReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getParamReply(buf), nil +} + +// getParamReply reads a byte slice into a GetParamReply value. +func getParamReply(buf []byte) *GetParamReply { + v := new(GetParamReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.IsParamRecognized = true + } else { + v.IsParamRecognized = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ValueHi = xgb.Get32(buf[b:]) + b += 4 + + v.ValueLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetParam +// getParamRequest writes a GetParam request to a byte slice. +func getParamRequest(c *xgb.Conn, Drawable xproto.Drawable, Param uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Param) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + return buf +} + +// SwapBuffersCookie is a cookie used only for SwapBuffers requests. +type SwapBuffersCookie struct { + *xgb.Cookie +} + +// SwapBuffers sends a checked request. +// If an error occurs, it will be returned with the reply by calling SwapBuffersCookie.Reply() +func SwapBuffers(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) SwapBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(swapBuffersRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return SwapBuffersCookie{cookie} +} + +// SwapBuffersUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwapBuffersUnchecked(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) SwapBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(swapBuffersRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return SwapBuffersCookie{cookie} +} + +// SwapBuffersReply represents the data returned from a SwapBuffers request. +type SwapBuffersReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + SwapHi uint32 + SwapLo uint32 +} + +// Reply blocks and returns the reply data for a SwapBuffers request. +func (cook SwapBuffersCookie) Reply() (*SwapBuffersReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return swapBuffersReply(buf), nil +} + +// swapBuffersReply reads a byte slice into a SwapBuffersReply value. +func swapBuffersReply(buf []byte) *SwapBuffersReply { + v := new(SwapBuffersReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.SwapHi = xgb.Get32(buf[b:]) + b += 4 + + v.SwapLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for SwapBuffers +// swapBuffersRequest writes a SwapBuffers request to a byte slice. +func swapBuffersRequest(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], TargetMscHi) + b += 4 + + xgb.Put32(buf[b:], TargetMscLo) + b += 4 + + xgb.Put32(buf[b:], DivisorHi) + b += 4 + + xgb.Put32(buf[b:], DivisorLo) + b += 4 + + xgb.Put32(buf[b:], RemainderHi) + b += 4 + + xgb.Put32(buf[b:], RemainderLo) + b += 4 + + return buf +} + +// SwapIntervalCookie is a cookie used only for SwapInterval requests. +type SwapIntervalCookie struct { + *xgb.Cookie +} + +// SwapInterval sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwapInterval(c *xgb.Conn, Drawable xproto.Drawable, Interval uint32) SwapIntervalCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapInterval' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(swapIntervalRequest(c, Drawable, Interval), cookie) + return SwapIntervalCookie{cookie} +} + +// SwapIntervalChecked sends a checked request. +// If an error occurs, it can be retrieved using SwapIntervalCookie.Check() +func SwapIntervalChecked(c *xgb.Conn, Drawable xproto.Drawable, Interval uint32) SwapIntervalCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapInterval' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(swapIntervalRequest(c, Drawable, Interval), cookie) + return SwapIntervalCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SwapIntervalCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SwapInterval +// swapIntervalRequest writes a SwapInterval request to a byte slice. +func swapIntervalRequest(c *xgb.Conn, Drawable xproto.Drawable, Interval uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Interval) + b += 4 + + return buf +} + +// WaitMSCCookie is a cookie used only for WaitMSC requests. +type WaitMSCCookie struct { + *xgb.Cookie +} + +// WaitMSC sends a checked request. +// If an error occurs, it will be returned with the reply by calling WaitMSCCookie.Reply() +func WaitMSC(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) WaitMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(waitMSCRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return WaitMSCCookie{cookie} +} + +// WaitMSCUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WaitMSCUnchecked(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) WaitMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(waitMSCRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return WaitMSCCookie{cookie} +} + +// WaitMSCReply represents the data returned from a WaitMSC request. +type WaitMSCReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + SbcHi uint32 + SbcLo uint32 +} + +// Reply blocks and returns the reply data for a WaitMSC request. +func (cook WaitMSCCookie) Reply() (*WaitMSCReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return waitMSCReply(buf), nil +} + +// waitMSCReply reads a byte slice into a WaitMSCReply value. +func waitMSCReply(buf []byte) *WaitMSCReply { + v := new(WaitMSCReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.SbcHi = xgb.Get32(buf[b:]) + b += 4 + + v.SbcLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for WaitMSC +// waitMSCRequest writes a WaitMSC request to a byte slice. +func waitMSCRequest(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], TargetMscHi) + b += 4 + + xgb.Put32(buf[b:], TargetMscLo) + b += 4 + + xgb.Put32(buf[b:], DivisorHi) + b += 4 + + xgb.Put32(buf[b:], DivisorLo) + b += 4 + + xgb.Put32(buf[b:], RemainderHi) + b += 4 + + xgb.Put32(buf[b:], RemainderLo) + b += 4 + + return buf +} + +// WaitSBCCookie is a cookie used only for WaitSBC requests. +type WaitSBCCookie struct { + *xgb.Cookie +} + +// WaitSBC sends a checked request. +// If an error occurs, it will be returned with the reply by calling WaitSBCCookie.Reply() +func WaitSBC(c *xgb.Conn, Drawable xproto.Drawable, TargetSbcHi uint32, TargetSbcLo uint32) WaitSBCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitSBC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(waitSBCRequest(c, Drawable, TargetSbcHi, TargetSbcLo), cookie) + return WaitSBCCookie{cookie} +} + +// WaitSBCUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WaitSBCUnchecked(c *xgb.Conn, Drawable xproto.Drawable, TargetSbcHi uint32, TargetSbcLo uint32) WaitSBCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitSBC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(waitSBCRequest(c, Drawable, TargetSbcHi, TargetSbcLo), cookie) + return WaitSBCCookie{cookie} +} + +// WaitSBCReply represents the data returned from a WaitSBC request. +type WaitSBCReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + SbcHi uint32 + SbcLo uint32 +} + +// Reply blocks and returns the reply data for a WaitSBC request. +func (cook WaitSBCCookie) Reply() (*WaitSBCReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return waitSBCReply(buf), nil +} + +// waitSBCReply reads a byte slice into a WaitSBCReply value. +func waitSBCReply(buf []byte) *WaitSBCReply { + v := new(WaitSBCReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.SbcHi = xgb.Get32(buf[b:]) + b += 4 + + v.SbcLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for WaitSBC +// waitSBCRequest writes a WaitSBC request to a byte slice. +func waitSBCRequest(c *xgb.Conn, Drawable xproto.Drawable, TargetSbcHi uint32, TargetSbcLo uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], TargetSbcHi) + b += 4 + + xgb.Put32(buf[b:], TargetSbcLo) + b += 4 + + return buf +} diff --git a/vend/xgb/examples/atoms/.gitignore b/vend/xgb/examples/atoms/.gitignore new file mode 100644 index 0000000..01e08a1 --- /dev/null +++ b/vend/xgb/examples/atoms/.gitignore @@ -0,0 +1,3 @@ +atoms +*.info +*.prof diff --git a/vend/xgb/examples/atoms/Makefile b/vend/xgb/examples/atoms/Makefile new file mode 100644 index 0000000..c192a37 --- /dev/null +++ b/vend/xgb/examples/atoms/Makefile @@ -0,0 +1,12 @@ +atoms: + go build + +test: atoms + ./atoms --requests 500000 --cpu 1 \ + --cpuprof cpu1.prof --memprof mem1.prof > atoms1.info 2>&1 + ./atoms --requests 500000 --cpu 2 \ + --cpuprof cpu2.prof --memprof mem2.prof > atoms2.info 2>&1 + ./atoms --requests 500000 --cpu 3 \ + --cpuprof cpu3.prof --memprof mem3.prof > atoms3.info 2>&1 + ./atoms --requests 500000 --cpu 6 \ + --cpuprof cpu6.prof --memprof mem6.prof > atoms6.info 2>&1 diff --git a/vend/xgb/examples/atoms/main.go b/vend/xgb/examples/atoms/main.go new file mode 100644 index 0000000..b94a772 --- /dev/null +++ b/vend/xgb/examples/atoms/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "runtime" + "runtime/pprof" + "time" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" +) + +var ( + flagRequests int + flagGOMAXPROCS int + flagCpuProfName string + flagMemProfName string +) + +func init() { + flag.IntVar(&flagRequests, "requests", 100000, "Number of atoms to intern.") + flag.IntVar(&flagGOMAXPROCS, "cpu", 1, "Value of GOMAXPROCS.") + flag.StringVar(&flagCpuProfName, "cpuprof", "cpu.prof", + "Name of CPU profile file.") + flag.StringVar(&flagMemProfName, "memprof", "mem.prof", + "Name of memory profile file.") + + flag.Parse() + + runtime.GOMAXPROCS(flagGOMAXPROCS) +} + +func seqNames(n int) []string { + names := make([]string, n) + for i := range names { + names[i] = fmt.Sprintf("NAME%d", i) + } + return names +} + +func main() { + X, err := xgb.NewConn() + if err != nil { + log.Fatal(err) + } + + names := seqNames(flagRequests) + + fcpu, err := os.Create(flagCpuProfName) + if err != nil { + log.Fatal(err) + } + defer fcpu.Close() + pprof.StartCPUProfile(fcpu) + defer pprof.StopCPUProfile() + + start := time.Now() + cookies := make([]xproto.InternAtomCookie, flagRequests) + for i := 0; i < flagRequests; i++ { + cookies[i] = xproto.InternAtom(X, + false, uint16(len(names[i])), names[i]) + } + for _, cookie := range cookies { + cookie.Reply() + } + fmt.Printf("Exec time: %s\n\n", time.Since(start)) + + fmem, err := os.Create(flagMemProfName) + if err != nil { + log.Fatal(err) + } + defer fmem.Close() + pprof.WriteHeapProfile(fmem) + + memStats := &runtime.MemStats{} + runtime.ReadMemStats(memStats) + + // This isn't right. I'm not sure what's wrong. + lastGcTime := time.Unix(int64(memStats.LastGC/1000000000), + int64(memStats.LastGC-memStats.LastGC/1000000000)) + + fmt.Printf("Alloc: %d\n", memStats.Alloc) + fmt.Printf("TotalAlloc: %d\n", memStats.TotalAlloc) + fmt.Printf("LastGC: %s\n", lastGcTime) + fmt.Printf("PauseTotalNs: %d\n", memStats.PauseTotalNs) + fmt.Printf("PauseNs: %d\n", memStats.PauseNs) + fmt.Printf("NumGC: %d\n", memStats.NumGC) +} diff --git a/vend/xgb/examples/create-window/main.go b/vend/xgb/examples/create-window/main.go new file mode 100644 index 0000000..a637d0e --- /dev/null +++ b/vend/xgb/examples/create-window/main.go @@ -0,0 +1,148 @@ +// Example create-window shows how to create a window, map it, resize it, +// and listen to structure and key events (i.e., when the window is resized +// by the window manager, or when key presses/releases are made when the +// window has focus). The events are printed to stdout. +package main + +import ( + "fmt" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" +) + +func main() { + X, err := xgb.NewConn() + if err != nil { + fmt.Println(err) + return + } + defer X.Close() + + // xproto.Setup retrieves the Setup information from the setup bytes + // gathered during connection. + setup := xproto.Setup(X) + + // This is the default screen with all its associated info. + screen := setup.DefaultScreen(X) + + // Any time a new resource (i.e., a window, pixmap, graphics context, etc.) + // is created, we need to generate a resource identifier. + // If the resource is a window, then use xproto.NewWindowId. If it's for + // a pixmap, then use xproto.NewPixmapId. And so on... + wid, _ := xproto.NewWindowId(X) + + // CreateWindow takes a boatload of parameters. + xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root, + 0, 0, 500, 500, 0, + xproto.WindowClassInputOutput, screen.RootVisual, 0, []uint32{}) + + // This call to ChangeWindowAttributes could be factored out and + // included with the above CreateWindow call, but it is left here for + // instructive purposes. It tells X to send us events when the 'structure' + // of the window is changed (i.e., when it is resized, mapped, unmapped, + // etc.) and when a key press or a key release has been made when the + // window has focus. + // We also set the 'BackPixel' to white so that the window isn't butt ugly. + xproto.ChangeWindowAttributes(X, wid, + xproto.CwBackPixel|xproto.CwEventMask, + []uint32{ // values must be in the order defined by the protocol + 0xffffffff, + xproto.EventMaskStructureNotify | + xproto.EventMaskKeyPress | + xproto.EventMaskKeyRelease, + }) + + // MapWindow makes the window we've created appear on the screen. + // We demonstrated the use of a 'checked' request here. + // A checked request is a fancy way of saying, "do error handling + // synchronously." Namely, if there is a problem with the MapWindow request, + // we'll get the error *here*. If we were to do a normal unchecked + // request (like the above CreateWindow and ChangeWindowAttributes + // requests), then we would only see the error arrive in the main event + // loop. + // + // Typically, checked requests are useful when you need to make sure they + // succeed. Since they are synchronous, they incur a round trip cost before + // the program can continue, but this is only going to be noticeable if + // you're issuing tons of requests in succession. + // + // Note that requests without replies are by default unchecked while + // requests *with* replies are checked by default. + err = xproto.MapWindowChecked(X, wid).Check() + if err != nil { + fmt.Printf("Checked Error for mapping window %d: %s\n", wid, err) + } else { + fmt.Printf("Map window %d successful!\n", wid) + } + + // This is an example of an invalid MapWindow request and what an error + // looks like. + err = xproto.MapWindowChecked(X, 0).Check() + if err != nil { + fmt.Printf("Checked Error for mapping window 0x1: %s\n", err) + } else { // neva + fmt.Printf("Map window 0x1 successful!\n") + } + + // Start the main event loop. + for { + // WaitForEvent either returns an event or an error and never both. + // If both are nil, then something went wrong and the loop should be + // halted. + // + // An error can only be seen here as a response to an unchecked + // request. + ev, xerr := X.WaitForEvent() + if ev == nil && xerr == nil { + fmt.Println("Both event and error are nil. Exiting...") + return + } + + if ev != nil { + fmt.Printf("Event: %s\n", ev) + } + if xerr != nil { + fmt.Printf("Error: %s\n", xerr) + } + + // This is how accepting events work: + // The application checks what event we got and reacts to it + // accordingly. All events are defined in the xproto subpackage. + // To receive events, we have to first register it using + // either xproto.CreateWindow or xproto.ChangeWindowAttributes. + switch ev.(type) { + case xproto.KeyPressEvent: + // See https://pkg.go.dev/github.com/jezek/xgb/xproto#KeyPressEvent + // for documentation about a key press event. + kpe := ev.(xproto.KeyPressEvent) + fmt.Printf("Key pressed: %d\n", kpe.Detail) + // The Detail value depends on the keyboard layout, + // for QWERTY, q is #24. + if kpe.Detail == 24 { + return // exit on q + } + case xproto.DestroyNotifyEvent: + // Depending on the user's desktop environment (especially + // window manager), killing a window might close the + // client's X connection (e. g. the default Ubuntu + // desktop environment). + // + // If that's the case for your environment, closing this example's window + // will also close the underlying Go program (because closing the X + // connection gives a nil event and EOF error). + // + // Consider how a single application might have multiple windows + // (e.g. an open popup or dialog, ...) + // + // With other DEs, the X connection will still stay open even after the + // X window is closed. For these DEs (e.g. i3) we have to check whether + // the WM sent us a DestroyNotifyEvent and close our program. + // + // For more information about closing windows while maintaining + // the X connection see + // https://github.com/jezek/xgbutil/blob/master/_examples/graceful-window-close/main.go + return + } + } +} diff --git a/vend/xgb/examples/doc.go b/vend/xgb/examples/doc.go new file mode 100644 index 0000000..b516851 --- /dev/null +++ b/vend/xgb/examples/doc.go @@ -0,0 +1,21 @@ +/* +Package examples contains a few different use cases of XGB, like creating +a window, reading properties, and querying for information about multiple +heads using the Xinerama or RandR extensions. + +If you're looking to get started quickly, I recommend checking out the +create-window example first. It is the most documented and probably covers +some of the more common bare bones cases of creating windows and responding +to events. + +If you're looking to query information about your window manager, +get-active-window is a start. However, to do anything extensive requires +a lot of boiler plate. To that end, I'd recommend use of a higher level +library (eg. xgbutil: https://github.com/jezek/xgbutil). + +There are also examples of using the Xinerama and RandR extensions, if you're +interested in querying information about your active heads. In RandR's case, +you can also reconfigure your heads, but the example doesn't cover that. + +*/ +package documentation diff --git a/vend/xgb/examples/get-active-window/main.go b/vend/xgb/examples/get-active-window/main.go new file mode 100644 index 0000000..37f374c --- /dev/null +++ b/vend/xgb/examples/get-active-window/main.go @@ -0,0 +1,61 @@ +// Example get-active-window reads the _NET_ACTIVE_WINDOW property of the root +// window and uses the result (a window id) to get the name of the window. +package main + +import ( + "fmt" + "log" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" +) + +func main() { + X, err := xgb.NewConn() + if err != nil { + log.Fatal(err) + } + + // Get the window id of the root window. + setup := xproto.Setup(X) + root := setup.DefaultScreen(X).Root + + // Get the atom id (i.e., intern an atom) of "_NET_ACTIVE_WINDOW". + aname := "_NET_ACTIVE_WINDOW" + activeAtom, err := xproto.InternAtom(X, true, uint16(len(aname)), + aname).Reply() + if err != nil { + log.Fatal(err) + } + + // Get the atom id (i.e., intern an atom) of "_NET_WM_NAME". + aname = "_NET_WM_NAME" + nameAtom, err := xproto.InternAtom(X, true, uint16(len(aname)), + aname).Reply() + if err != nil { + log.Fatal(err) + } + + // Get the actual value of _NET_ACTIVE_WINDOW. + // Note that 'reply.Value' is just a slice of bytes, so we use an + // XGB helper function, 'Get32', to pull an unsigned 32-bit integer out + // of the byte slice. We then convert it to an X resource id so it can + // be used to get the name of the window in the next GetProperty request. + reply, err := xproto.GetProperty(X, false, root, activeAtom.Atom, + xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() + if err != nil { + log.Fatal(err) + } + windowId := xproto.Window(xgb.Get32(reply.Value)) + fmt.Printf("Active window id: %X\n", windowId) + + // Now get the value of _NET_WM_NAME for the active window. + // Note that this time, we simply convert the resulting byte slice, + // reply.Value, to a string. + reply, err = xproto.GetProperty(X, false, windowId, nameAtom.Atom, + xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() + if err != nil { + log.Fatal(err) + } + fmt.Printf("Active window name: %s\n", string(reply.Value)) +} diff --git a/vend/xgb/examples/randr/main.go b/vend/xgb/examples/randr/main.go new file mode 100644 index 0000000..24db999 --- /dev/null +++ b/vend/xgb/examples/randr/main.go @@ -0,0 +1,92 @@ +// Example randr uses the randr protocol to get information about the active +// heads. It also listens for events that are sent when the head configuration +// changes. Since it listens to events, you'll have to manually kill this +// process when you're done (i.e., ctrl+c.) +// +// While this program is running, if you use 'xrandr' to reconfigure your +// heads, you should see event information dumped to standard out. +// +// For more information, please see the RandR protocol spec: +// http://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt +package main + +import ( + "fmt" + "log" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/randr" + "github.com/jezek/xgb/xproto" +) + +func main() { + X, _ := xgb.NewConn() + + // Every extension must be initialized before it can be used. + err := randr.Init(X) + if err != nil { + log.Fatal(err) + } + + // Get the root window on the default screen. + root := xproto.Setup(X).DefaultScreen(X).Root + + // Gets the current screen resources. Screen resources contains a list + // of names, crtcs, outputs and modes, among other things. + resources, err := randr.GetScreenResources(X, root).Reply() + if err != nil { + log.Fatal(err) + } + + // Iterate through all of the outputs and show some of their info. + for _, output := range resources.Outputs { + info, err := randr.GetOutputInfo(X, output, 0).Reply() + if err != nil { + log.Fatal(err) + } + + if info.Connection == randr.ConnectionConnected { + bestMode := info.Modes[0] + for _, mode := range resources.Modes { + if mode.Id == uint32(bestMode) { + fmt.Printf("Width: %d, Height: %d\n", + mode.Width, mode.Height) + } + } + } + } + + fmt.Println("") + + // Iterate through all of the crtcs and show some of their info. + for _, crtc := range resources.Crtcs { + info, err := randr.GetCrtcInfo(X, crtc, 0).Reply() + if err != nil { + log.Fatal(err) + } + fmt.Printf("X: %d, Y: %d, Width: %d, Height: %d\n", + info.X, info.Y, info.Width, info.Height) + } + + // Tell RandR to send us events. (I think these are all of them, as of 1.3.) + err = randr.SelectInputChecked(X, root, + randr.NotifyMaskScreenChange| + randr.NotifyMaskCrtcChange| + randr.NotifyMaskOutputChange| + randr.NotifyMaskOutputProperty).Check() + if err != nil { + log.Fatal(err) + } + + // Listen to events and just dump them to standard out. + // A more involved approach will have to read the 'U' field of + // RandrNotifyEvent, which is a union (really a struct) of type + // RanrNotifyDataUnion. + for { + ev, err := X.WaitForEvent() + if err != nil { + log.Fatal(err) + } + fmt.Println(ev) + } +} diff --git a/vend/xgb/examples/shapes/main.go b/vend/xgb/examples/shapes/main.go new file mode 100644 index 0000000..aecc21f --- /dev/null +++ b/vend/xgb/examples/shapes/main.go @@ -0,0 +1,306 @@ +// The shapes example shows how to draw basic shapes into a window. +// It can be considered the Go equivalent of +// https://x.org/releases/X11R7.5/doc/libxcb/tutorial/#drawingprim +// Four points, a single polyline, two line segments, +// two rectangles and two arcs are drawn. +// In addition to this, we will also write some text +// and fill a rectangle. +package main + +import ( + "fmt" + "unicode/utf16" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" +) + +func main() { + X, err := xgb.NewConn() + if err != nil { + fmt.Println("error connecting to X:", err) + return + } + defer X.Close() + + setup := xproto.Setup(X) + screen := setup.DefaultScreen(X) + wid, err := xproto.NewWindowId(X) + if err != nil { + fmt.Println("error creating window id:", err) + return + } + + draw := xproto.Drawable(wid) // for now, we simply draw into the window + + // Create the window + xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root, + 0, 0, 180, 200, 8, // X, Y, width, height, *border width* + xproto.WindowClassInputOutput, screen.RootVisual, + xproto.CwBackPixel|xproto.CwEventMask, + []uint32{screen.WhitePixel, xproto.EventMaskStructureNotify | xproto.EventMaskExposure}) + + // Map the window on the screen + xproto.MapWindow(X, wid) + + // Up to here everything is the same as in the `create-window` example. + // We opened a connection, created and mapped the window. + // But this time we'll be drawing some basic shapes. + // Note how this time the border width is set to 8 instead of 0. + // + // First of all we need to create a context to draw with. + // The graphics context combines all properties (e.g. color, line width, font, fill style, ...) + // that should be used to draw something. All available properties + // + // These properties can be set by or'ing their keys (xproto.Gc*) + // and adding the value to the end of the values array. + // The order in which the values have to be given corresponds to the order that they defined + // mentioned in `xproto`. + // + // Here we create a new graphics context + // which only has the foreground (color) value set to black: + foreground, err := xproto.NewGcontextId(X) + if err != nil { + fmt.Println("error creating foreground context:", err) + return + } + + mask := uint32(xproto.GcForeground) + values := []uint32{screen.BlackPixel} + xproto.CreateGC(X, foreground, draw, mask, values) + + // It is possible to set the foreground value to something different. + // In production, this should use xorg color maps instead for compatibility + // but for demonstration setting the color directly also works. + // For more information on color maps, see the xcb documentation: + // https://x.org/releases/X11R7.5/doc/libxcb/tutorial/#usecolor + red, err := xproto.NewGcontextId(X) + if err != nil { + fmt.Println("error creating red context:", err) + return + } + + mask = uint32(xproto.GcForeground) + values = []uint32{0xff0000} + xproto.CreateGC(X, red, draw, mask, values) + + // We'll create another graphics context that draws thick lines: + thick, err := xproto.NewGcontextId(X) + if err != nil { + fmt.Println("error creating thick context:", err) + return + } + + mask = uint32(xproto.GcLineWidth) + values = []uint32{10} + xproto.CreateGC(X, thick, draw, mask, values) + + // It is even possible to set multiple properties at once. + // Only remember to put the values in the same order as they're + // defined in `xproto`: + // Foreground is defined first, so we also set it's value first. + // LineWidth comes second. + blue, err := xproto.NewGcontextId(X) + if err != nil { + fmt.Println("error creating blue context:", err) + return + } + + mask = uint32(xproto.GcForeground | xproto.GcLineWidth) + values = []uint32{0x0000ff, 4} + xproto.CreateGC(X, blue, draw, mask, values) + + // Properties of an already created gc can also be changed + // if the original values aren't needed anymore. + // In this case, we will change the line width + // and cap (line corner) style of our foreground context, + // to smooth out the polyline: + mask = uint32(xproto.GcLineWidth | xproto.GcCapStyle) + values = []uint32{3, xproto.CapStyleRound} + xproto.ChangeGC(X, foreground, mask, values) + + // Writing text needs a bit more setup -- we first have + // to open the required font. + font, err := xproto.NewFontId(X) + if err != nil { + fmt.Println("error creating font id:", err) + return + } + + // The font identifier that has to be passed to X for opening the font + // sets all font properties: + // publisher-family-weight-slant-width-adstyl-pxlsz-ptSz-resx-resy-spc-avgWidth-registry-encoding + // For all available fonts, install and run xfontsel. + // + // To load any available font, set all fields to an asterisk. + // To specify a font, set one or multiple fields. + // This can also be seen in xfontsel -- initially every field is set to *, + // however, the more fields are set, the fewer fonts match. + // + // Using a specific font (e.g. Gnu Unifont) can be as easy as + // "-gnu-unifont-*-*-*-*-16-*-*-*-*-*-*-*" + // + // To load any font that is encoded for usage + // with Unicode characters, one would use + // fontname := "-*-*-*-*-*-*-14-*-*-*-*-*-iso10646-1" + // + // For now, we'll simply stick with the fixed font which is available + // to every X session: + fontname := "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*" + err = xproto.OpenFontChecked(X, font, uint16(len(fontname)), fontname).Check() + if err != nil { + fmt.Println("failed opening the font:", err) + return + } + + // And create a context from it. We simply pass the font's ID to the GcFont property. + textCtx, err := xproto.NewGcontextId(X) + if err != nil { + fmt.Println("error creating text context:", err) + return + } + + mask = uint32(xproto.GcForeground | xproto.GcBackground | xproto.GcFont) + values = []uint32{screen.BlackPixel, screen.WhitePixel, uint32(font)} + xproto.CreateGC(X, textCtx, draw, mask, values) + text := convertStringToChar2b("Hellö World!") // Unicode capable! + + // Close the font handle: + xproto.CloseFont(X, font) + + // After all, writing text is way more comfortable using Xft - it supports TrueType, + // and overall better configuration. + + points := []xproto.Point{ + {X: 10, Y: 10}, + {X: 20, Y: 10}, + {X: 30, Y: 10}, + {X: 40, Y: 10}, + } + + // A polyline is essentially a line with multiple points. + // The first point is placed absolutely inside the window, + // while every other point is placed relative to the one before it. + polyline := []xproto.Point{ + {X: 50, Y: 10}, + {X: 5, Y: 20}, // move 5 to the right, 20 down + {X: 25, Y: -20}, // move 25 to the right, 20 up - notice how this point is level again with the first point + {X: 10, Y: 10}, // move 10 to the right, 10 down + } + + segments := []xproto.Segment{ + {X1: 100, Y1: 10, X2: 140, Y2: 30}, + {X1: 110, Y1: 25, X2: 130, Y2: 60}, + {X1: 0, Y1: 160, X2: 90, Y2: 100}, + } + + // Rectangles have a start coordinate (upper left) and width and height. + rectangles := []xproto.Rectangle{ + {X: 10, Y: 50, Width: 40, Height: 20}, + {X: 80, Y: 50, Width: 10, Height: 40}, + } + + // This rectangle we will use to demonstrate filling a shape. + rectangles2 := []xproto.Rectangle{ + {X: 150, Y: 50, Width: 20, Height: 60}, + } + + // Arcs are defined by a top left position (notice where the third line goes to) + // their width and height, a starting and end angle. + // Angles are defined in units of 1/64 of a single degree, + // so we have to multiply the degrees by 64 (or left shift them by 6). + arcs := []xproto.Arc{ + {X: 10, Y: 100, Width: 60, Height: 40, Angle1: 0 << 6, Angle2: 90 << 6}, + {X: 90, Y: 100, Width: 55, Height: 40, Angle1: 20 << 6, Angle2: 270 << 6}, + } + + for { + evt, err := X.WaitForEvent() + + if err != nil { + fmt.Println("error reading event:", err) + return + } else if evt == nil { + return + } + + switch evt.(type) { + case xproto.ExposeEvent: + // Draw the four points we specified earlier. + // Notice how we use the `foreground` context to draw them in black. + // Also notice how even though we changed the line width to 3, + // these still only appear as a single pixel. + // To draw points that are bigger than a single pixel, + // one has to either fill rectangles, circles or polygons. + xproto.PolyPoint(X, xproto.CoordModeOrigin, draw, foreground, points) + + // Draw the polyline. This time we specified `xproto.CoordModePrevious`, + // which means that every point is placed relatively to the previous. + // If we were to use `xproto.CoordModeOrigin` instead, + // we could specify each point absolutely on the screen. + // It is also possible to use `xproto.CoordModePrevious` for drawing *points* + // which means that each point would be specified relative to the previous one, + // just as we did with the polyline. + xproto.PolyLine(X, xproto.CoordModePrevious, draw, foreground, polyline) + + // Draw two lines in red. + xproto.PolySegment(X, draw, red, segments) + + // Draw two thick rectangles. + // The line width only specifies the width of the outline. + // Notice how the second rectangle gets completely filled + // due to the line width. + xproto.PolyRectangle(X, draw, thick, rectangles) + + // Draw the circular arcs in blue. + xproto.PolyArc(X, draw, blue, arcs) + + // There's also a fill variant for all drawing commands: + xproto.PolyFillRectangle(X, draw, red, rectangles2) + + // Draw the text. Xorg currently knows two ways of specifying text: + // a) the (extended) ASCII encoding using ImageText8(..., []byte) + // b) UTF16 encoding using ImageText16(..., []Char2b) -- Char2b is + // a structure consisting of two bytes. + // At the bottom of this example, there are two utility functions that help + // convert a go string into an array of Char2b's. + xproto.ImageText16(X, byte(len(text)), draw, textCtx, 10, 160, text) + + case xproto.DestroyNotifyEvent: + return + } + } +} + +// Char2b is defined as +// Byte1 byte +// Byte2 byte +// and is used as a utf16 character. +// This function takes a string and converts each rune into a char2b. +func convertStringToChar2b(s string) []xproto.Char2b { + var chars []xproto.Char2b + var p []uint16 + + for _, r := range []rune(s) { + p = utf16.Encode([]rune{r}) + if len(p) == 1 { + chars = append(chars, convertUint16ToChar2b(p[0])) + } else { + // If the utf16 representation is larger than 2 bytes + // we can not use it and insert a blank instead: + chars = append(chars, xproto.Char2b{Byte1: 0, Byte2: 32}) + } + } + + return chars +} + +// convertUint16ToChar2b converts a uint16 (which is basically two bytes) +// into a Char2b by using the higher 8 bits of u as Byte1 +// and the lower 8 bits of u as Byte2. +func convertUint16ToChar2b(u uint16) xproto.Char2b { + return xproto.Char2b{ + Byte1: byte((u & 0xff00) >> 8), + Byte2: byte((u & 0x00ff)), + } +} diff --git a/vend/xgb/examples/xinerama/main.go b/vend/xgb/examples/xinerama/main.go new file mode 100644 index 0000000..a7e1531 --- /dev/null +++ b/vend/xgb/examples/xinerama/main.go @@ -0,0 +1,40 @@ +// Example xinerama shows how to query the geometry of all active heads. +package main + +import ( + "fmt" + "log" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xinerama" +) + +func main() { + X, err := xgb.NewConn() + if err != nil { + log.Fatal(err) + } + + // Initialize the Xinerama extension. + // The appropriate 'Init' function must be run for *every* + // extension before any of its requests can be used. + err = xinerama.Init(X) + if err != nil { + log.Fatal(err) + } + + // Issue a request to get the screen information. + reply, err := xinerama.QueryScreens(X).Reply() + if err != nil { + log.Fatal(err) + } + + // reply.Number is the number of active heads, while reply.ScreenInfo + // is a slice of XineramaScreenInfo containing the rectangle geometry + // of each head. + fmt.Printf("Number of heads: %d\n", reply.Number) + for i, screen := range reply.ScreenInfo { + fmt.Printf("%d :: X: %d, Y: %d, Width: %d, Height: %d\n", + i, screen.XOrg, screen.YOrg, screen.Width, screen.Height) + } +} diff --git a/vend/xgb/ge/ge.go b/vend/xgb/ge/ge.go new file mode 100644 index 0000000..1466744 --- /dev/null +++ b/vend/xgb/ge/ge.go @@ -0,0 +1,165 @@ +// Package ge is the X client API for the Generic Event Extension extension. +package ge + +// This file is automatically generated from ge.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the Generic Event Extension extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 23, "Generic Event Extension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named Generic Event Extension could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["Generic Event Extension"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["Generic Event Extension"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["Generic Event Extension"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["Generic Event Extension"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["Generic Event Extension"] = make(map[int]xgb.NewErrorFun) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Generic Event Extension"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'Generic Event Extension'. ge.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["Generic Event Extension"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'Generic Event Extension'. ge.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint16 + MinorVersion uint16 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + b += 20 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["Generic Event Extension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], ClientMajorVersion) + b += 2 + + xgb.Put16(buf[b:], ClientMinorVersion) + b += 2 + + return buf +} diff --git a/vend/xgb/glx/glx.go b/vend/xgb/glx/glx.go new file mode 100644 index 0000000..8950862 --- /dev/null +++ b/vend/xgb/glx/glx.go @@ -0,0 +1,10930 @@ +// Package glx is the X client API for the GLX extension. +package glx + +// This file is automatically generated from glx.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the GLX extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 3, "GLX").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named GLX could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["GLX"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["GLX"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["GLX"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["GLX"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["GLX"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadContext is the error number for a BadBadContext. +const BadBadContext = 0 + +type BadContextError GenericError + +// BadContextErrorNew constructs a BadContextError value that implements xgb.Error from a byte slice. +func BadContextErrorNew(buf []byte) xgb.Error { + v := BadContextError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadContext" + return v +} + +// SequenceId returns the sequence id attached to the BadBadContext error. +// This is mostly used internally. +func (err BadContextError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadContext error. If no bad value exists, 0 is returned. +func (err BadContextError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadContext error. +func (err BadContextError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadContext {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][0] = BadContextErrorNew +} + +// BadBadContextState is the error number for a BadBadContextState. +const BadBadContextState = 1 + +type BadContextStateError GenericError + +// BadContextStateErrorNew constructs a BadContextStateError value that implements xgb.Error from a byte slice. +func BadContextStateErrorNew(buf []byte) xgb.Error { + v := BadContextStateError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadContextState" + return v +} + +// SequenceId returns the sequence id attached to the BadBadContextState error. +// This is mostly used internally. +func (err BadContextStateError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadContextState error. If no bad value exists, 0 is returned. +func (err BadContextStateError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadContextState error. +func (err BadContextStateError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadContextState {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][1] = BadContextStateErrorNew +} + +// BadBadContextTag is the error number for a BadBadContextTag. +const BadBadContextTag = 4 + +type BadContextTagError GenericError + +// BadContextTagErrorNew constructs a BadContextTagError value that implements xgb.Error from a byte slice. +func BadContextTagErrorNew(buf []byte) xgb.Error { + v := BadContextTagError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadContextTag" + return v +} + +// SequenceId returns the sequence id attached to the BadBadContextTag error. +// This is mostly used internally. +func (err BadContextTagError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadContextTag error. If no bad value exists, 0 is returned. +func (err BadContextTagError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadContextTag error. +func (err BadContextTagError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadContextTag {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][4] = BadContextTagErrorNew +} + +// BadBadCurrentDrawable is the error number for a BadBadCurrentDrawable. +const BadBadCurrentDrawable = 11 + +type BadCurrentDrawableError GenericError + +// BadCurrentDrawableErrorNew constructs a BadCurrentDrawableError value that implements xgb.Error from a byte slice. +func BadCurrentDrawableErrorNew(buf []byte) xgb.Error { + v := BadCurrentDrawableError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadCurrentDrawable" + return v +} + +// SequenceId returns the sequence id attached to the BadBadCurrentDrawable error. +// This is mostly used internally. +func (err BadCurrentDrawableError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadCurrentDrawable error. If no bad value exists, 0 is returned. +func (err BadCurrentDrawableError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadCurrentDrawable error. +func (err BadCurrentDrawableError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadCurrentDrawable {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][11] = BadCurrentDrawableErrorNew +} + +// BadBadCurrentWindow is the error number for a BadBadCurrentWindow. +const BadBadCurrentWindow = 5 + +type BadCurrentWindowError GenericError + +// BadCurrentWindowErrorNew constructs a BadCurrentWindowError value that implements xgb.Error from a byte slice. +func BadCurrentWindowErrorNew(buf []byte) xgb.Error { + v := BadCurrentWindowError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadCurrentWindow" + return v +} + +// SequenceId returns the sequence id attached to the BadBadCurrentWindow error. +// This is mostly used internally. +func (err BadCurrentWindowError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadCurrentWindow error. If no bad value exists, 0 is returned. +func (err BadCurrentWindowError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadCurrentWindow error. +func (err BadCurrentWindowError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadCurrentWindow {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][5] = BadCurrentWindowErrorNew +} + +// BadBadDrawable is the error number for a BadBadDrawable. +const BadBadDrawable = 2 + +type BadDrawableError GenericError + +// BadDrawableErrorNew constructs a BadDrawableError value that implements xgb.Error from a byte slice. +func BadDrawableErrorNew(buf []byte) xgb.Error { + v := BadDrawableError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadDrawable" + return v +} + +// SequenceId returns the sequence id attached to the BadBadDrawable error. +// This is mostly used internally. +func (err BadDrawableError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadDrawable error. If no bad value exists, 0 is returned. +func (err BadDrawableError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadDrawable error. +func (err BadDrawableError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadDrawable {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][2] = BadDrawableErrorNew +} + +// BadBadFBConfig is the error number for a BadBadFBConfig. +const BadBadFBConfig = 9 + +type BadFBConfigError GenericError + +// BadFBConfigErrorNew constructs a BadFBConfigError value that implements xgb.Error from a byte slice. +func BadFBConfigErrorNew(buf []byte) xgb.Error { + v := BadFBConfigError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadFBConfig" + return v +} + +// SequenceId returns the sequence id attached to the BadBadFBConfig error. +// This is mostly used internally. +func (err BadFBConfigError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadFBConfig error. If no bad value exists, 0 is returned. +func (err BadFBConfigError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadFBConfig error. +func (err BadFBConfigError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadFBConfig {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][9] = BadFBConfigErrorNew +} + +// BadBadLargeRequest is the error number for a BadBadLargeRequest. +const BadBadLargeRequest = 7 + +type BadLargeRequestError GenericError + +// BadLargeRequestErrorNew constructs a BadLargeRequestError value that implements xgb.Error from a byte slice. +func BadLargeRequestErrorNew(buf []byte) xgb.Error { + v := BadLargeRequestError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadLargeRequest" + return v +} + +// SequenceId returns the sequence id attached to the BadBadLargeRequest error. +// This is mostly used internally. +func (err BadLargeRequestError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadLargeRequest error. If no bad value exists, 0 is returned. +func (err BadLargeRequestError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadLargeRequest error. +func (err BadLargeRequestError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadLargeRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][7] = BadLargeRequestErrorNew +} + +// BadBadPbuffer is the error number for a BadBadPbuffer. +const BadBadPbuffer = 10 + +type BadPbufferError GenericError + +// BadPbufferErrorNew constructs a BadPbufferError value that implements xgb.Error from a byte slice. +func BadPbufferErrorNew(buf []byte) xgb.Error { + v := BadPbufferError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadPbuffer" + return v +} + +// SequenceId returns the sequence id attached to the BadBadPbuffer error. +// This is mostly used internally. +func (err BadPbufferError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadPbuffer error. If no bad value exists, 0 is returned. +func (err BadPbufferError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadPbuffer error. +func (err BadPbufferError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadPbuffer {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][10] = BadPbufferErrorNew +} + +// BadBadPixmap is the error number for a BadBadPixmap. +const BadBadPixmap = 3 + +type BadPixmapError GenericError + +// BadPixmapErrorNew constructs a BadPixmapError value that implements xgb.Error from a byte slice. +func BadPixmapErrorNew(buf []byte) xgb.Error { + v := BadPixmapError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadPixmap" + return v +} + +// SequenceId returns the sequence id attached to the BadBadPixmap error. +// This is mostly used internally. +func (err BadPixmapError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadPixmap error. If no bad value exists, 0 is returned. +func (err BadPixmapError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadPixmap error. +func (err BadPixmapError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadPixmap {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][3] = BadPixmapErrorNew +} + +// BadBadRenderRequest is the error number for a BadBadRenderRequest. +const BadBadRenderRequest = 6 + +type BadRenderRequestError GenericError + +// BadRenderRequestErrorNew constructs a BadRenderRequestError value that implements xgb.Error from a byte slice. +func BadRenderRequestErrorNew(buf []byte) xgb.Error { + v := BadRenderRequestError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadRenderRequest" + return v +} + +// SequenceId returns the sequence id attached to the BadBadRenderRequest error. +// This is mostly used internally. +func (err BadRenderRequestError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadRenderRequest error. If no bad value exists, 0 is returned. +func (err BadRenderRequestError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadRenderRequest error. +func (err BadRenderRequestError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadRenderRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][6] = BadRenderRequestErrorNew +} + +// BadBadWindow is the error number for a BadBadWindow. +const BadBadWindow = 12 + +type BadWindowError GenericError + +// BadWindowErrorNew constructs a BadWindowError value that implements xgb.Error from a byte slice. +func BadWindowErrorNew(buf []byte) xgb.Error { + v := BadWindowError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "BadWindow" + return v +} + +// SequenceId returns the sequence id attached to the BadBadWindow error. +// This is mostly used internally. +func (err BadWindowError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadWindow error. If no bad value exists, 0 is returned. +func (err BadWindowError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadWindow error. +func (err BadWindowError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadWindow {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][12] = BadWindowErrorNew +} + +type Bool32 uint32 + +// BufferSwapComplete is the event number for a BufferSwapCompleteEvent. +const BufferSwapComplete = 1 + +type BufferSwapCompleteEvent struct { + Sequence uint16 + // padding: 1 bytes + EventType uint16 + // padding: 2 bytes + Drawable Drawable + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + Sbc uint32 +} + +// BufferSwapCompleteEventNew constructs a BufferSwapCompleteEvent value that implements xgb.Event from a byte slice. +func BufferSwapCompleteEventNew(buf []byte) xgb.Event { + v := BufferSwapCompleteEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.EventType = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Drawable = Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.Sbc = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Bytes writes a BufferSwapCompleteEvent value to a byte slice. +func (v BufferSwapCompleteEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 1 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put16(buf[b:], v.EventType) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put32(buf[b:], v.UstHi) + b += 4 + + xgb.Put32(buf[b:], v.UstLo) + b += 4 + + xgb.Put32(buf[b:], v.MscHi) + b += 4 + + xgb.Put32(buf[b:], v.MscLo) + b += 4 + + xgb.Put32(buf[b:], v.Sbc) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the BufferSwapComplete event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v BufferSwapCompleteEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of BufferSwapCompleteEvent. +func (v BufferSwapCompleteEvent) String() string { + fieldVals := make([]string, 0, 9) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("EventType: %d", v.EventType)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("UstHi: %d", v.UstHi)) + fieldVals = append(fieldVals, xgb.Sprintf("UstLo: %d", v.UstLo)) + fieldVals = append(fieldVals, xgb.Sprintf("MscHi: %d", v.MscHi)) + fieldVals = append(fieldVals, xgb.Sprintf("MscLo: %d", v.MscLo)) + fieldVals = append(fieldVals, xgb.Sprintf("Sbc: %d", v.Sbc)) + return "BufferSwapComplete {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["GLX"][1] = BufferSwapCompleteEventNew +} + +type Context uint32 + +func NewContextId(c *xgb.Conn) (Context, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Context(id), nil +} + +type ContextTag uint32 + +type Drawable uint32 + +func NewDrawableId(c *xgb.Conn) (Drawable, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Drawable(id), nil +} + +type Fbconfig uint32 + +func NewFbconfigId(c *xgb.Conn) (Fbconfig, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Fbconfig(id), nil +} + +type Float32 float64 + +type Float64 float64 + +// BadGLXBadProfileARB is the error number for a BadGLXBadProfileARB. +const BadGLXBadProfileARB = 13 + +type GLXBadProfileARBError GenericError + +// GLXBadProfileARBErrorNew constructs a GLXBadProfileARBError value that implements xgb.Error from a byte slice. +func GLXBadProfileARBErrorNew(buf []byte) xgb.Error { + v := GLXBadProfileARBError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "GLXBadProfileARB" + return v +} + +// SequenceId returns the sequence id attached to the BadGLXBadProfileARB error. +// This is mostly used internally. +func (err GLXBadProfileARBError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadGLXBadProfileARB error. If no bad value exists, 0 is returned. +func (err GLXBadProfileARBError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadGLXBadProfileARB error. +func (err GLXBadProfileARBError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadGLXBadProfileARB {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][13] = GLXBadProfileARBErrorNew +} + +const ( + GcGlCurrentBit = 1 + GcGlPointBit = 2 + GcGlLineBit = 4 + GcGlPolygonBit = 8 + GcGlPolygonStippleBit = 16 + GcGlPixelModeBit = 32 + GcGlLightingBit = 64 + GcGlFogBit = 128 + GcGlDepthBufferBit = 256 + GcGlAccumBufferBit = 512 + GcGlStencilBufferBit = 1024 + GcGlViewportBit = 2048 + GcGlTransformBit = 4096 + GcGlEnableBit = 8192 + GcGlColorBufferBit = 16384 + GcGlHintBit = 32768 + GcGlEvalBit = 65536 + GcGlListBit = 131072 + GcGlTextureBit = 262144 + GcGlScissorBit = 524288 + GcGlAllAttribBits = 16777215 +) + +// BadGeneric is the error number for a BadGeneric. +const BadGeneric = -1 + +type GenericError struct { + Sequence uint16 + NiceName string + BadValue uint32 + MinorOpcode uint16 + MajorOpcode byte + // padding: 21 bytes +} + +// GenericErrorNew constructs a GenericError value that implements xgb.Error from a byte slice. +func GenericErrorNew(buf []byte) xgb.Error { + v := GenericError{} + v.NiceName = "Generic" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.BadValue = xgb.Get32(buf[b:]) + b += 4 + + v.MinorOpcode = xgb.Get16(buf[b:]) + b += 2 + + v.MajorOpcode = buf[b] + b += 1 + + b += 21 // padding + + return v +} + +// SequenceId returns the sequence id attached to the BadGeneric error. +// This is mostly used internally. +func (err GenericError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadGeneric error. If no bad value exists, 0 is returned. +func (err GenericError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadGeneric error. + +func (err GenericError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadGeneric {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][-1] = GenericErrorNew +} + +const ( + PbcdtWindow = 32793 + PbcdtPbuffer = 32794 +) + +const ( + PbcetDamaged = 32791 + PbcetSaved = 32792 +) + +type Pbuffer uint32 + +func NewPbufferId(c *xgb.Conn) (Pbuffer, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Pbuffer(id), nil +} + +// PbufferClobber is the event number for a PbufferClobberEvent. +const PbufferClobber = 0 + +type PbufferClobberEvent struct { + Sequence uint16 + // padding: 1 bytes + EventType uint16 + DrawType uint16 + Drawable Drawable + BMask uint32 + AuxBuffer uint16 + X uint16 + Y uint16 + Width uint16 + Height uint16 + Count uint16 + // padding: 4 bytes +} + +// PbufferClobberEventNew constructs a PbufferClobberEvent value that implements xgb.Event from a byte slice. +func PbufferClobberEventNew(buf []byte) xgb.Event { + v := PbufferClobberEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.EventType = xgb.Get16(buf[b:]) + b += 2 + + v.DrawType = xgb.Get16(buf[b:]) + b += 2 + + v.Drawable = Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.BMask = xgb.Get32(buf[b:]) + b += 4 + + v.AuxBuffer = xgb.Get16(buf[b:]) + b += 2 + + v.X = xgb.Get16(buf[b:]) + b += 2 + + v.Y = xgb.Get16(buf[b:]) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Count = xgb.Get16(buf[b:]) + b += 2 + + b += 4 // padding + + return v +} + +// Bytes writes a PbufferClobberEvent value to a byte slice. +func (v PbufferClobberEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put16(buf[b:], v.EventType) + b += 2 + + xgb.Put16(buf[b:], v.DrawType) + b += 2 + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put32(buf[b:], v.BMask) + b += 4 + + xgb.Put16(buf[b:], v.AuxBuffer) + b += 2 + + xgb.Put16(buf[b:], v.X) + b += 2 + + xgb.Put16(buf[b:], v.Y) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.Count) + b += 2 + + b += 4 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the PbufferClobber event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v PbufferClobberEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of PbufferClobberEvent. +func (v PbufferClobberEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("EventType: %d", v.EventType)) + fieldVals = append(fieldVals, xgb.Sprintf("DrawType: %d", v.DrawType)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("BMask: %d", v.BMask)) + fieldVals = append(fieldVals, xgb.Sprintf("AuxBuffer: %d", v.AuxBuffer)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count)) + return "PbufferClobber {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["GLX"][0] = PbufferClobberEventNew +} + +type Pixmap uint32 + +func NewPixmapId(c *xgb.Conn) (Pixmap, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Pixmap(id), nil +} + +const ( + RmGlRender = 7168 + RmGlFeedback = 7169 + RmGlSelect = 7170 +) + +// BadUnsupportedPrivateRequest is the error number for a BadUnsupportedPrivateRequest. +const BadUnsupportedPrivateRequest = 8 + +type UnsupportedPrivateRequestError GenericError + +// UnsupportedPrivateRequestErrorNew constructs a UnsupportedPrivateRequestError value that implements xgb.Error from a byte slice. +func UnsupportedPrivateRequestErrorNew(buf []byte) xgb.Error { + v := UnsupportedPrivateRequestError(GenericErrorNew(buf).(GenericError)) + v.NiceName = "UnsupportedPrivateRequest" + return v +} + +// SequenceId returns the sequence id attached to the BadUnsupportedPrivateRequest error. +// This is mostly used internally. +func (err UnsupportedPrivateRequestError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadUnsupportedPrivateRequest error. If no bad value exists, 0 is returned. +func (err UnsupportedPrivateRequestError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadUnsupportedPrivateRequest error. +func (err UnsupportedPrivateRequestError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadUnsupportedPrivateRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["GLX"][8] = UnsupportedPrivateRequestErrorNew +} + +type Window uint32 + +func NewWindowId(c *xgb.Conn) (Window, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Window(id), nil +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AreTexturesResidentCookie is a cookie used only for AreTexturesResident requests. +type AreTexturesResidentCookie struct { + *xgb.Cookie +} + +// AreTexturesResident sends a checked request. +// If an error occurs, it will be returned with the reply by calling AreTexturesResidentCookie.Reply() +func AreTexturesResident(c *xgb.Conn, ContextTag ContextTag, N int32, Textures []uint32) AreTexturesResidentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'AreTexturesResident' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(areTexturesResidentRequest(c, ContextTag, N, Textures), cookie) + return AreTexturesResidentCookie{cookie} +} + +// AreTexturesResidentUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AreTexturesResidentUnchecked(c *xgb.Conn, ContextTag ContextTag, N int32, Textures []uint32) AreTexturesResidentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'AreTexturesResident' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(areTexturesResidentRequest(c, ContextTag, N, Textures), cookie) + return AreTexturesResidentCookie{cookie} +} + +// AreTexturesResidentReply represents the data returned from a AreTexturesResident request. +type AreTexturesResidentReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal Bool32 + // padding: 20 bytes + Data []bool // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a AreTexturesResident request. +func (cook AreTexturesResidentCookie) Reply() (*AreTexturesResidentReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return areTexturesResidentReply(buf), nil +} + +// areTexturesResidentReply reads a byte slice into a AreTexturesResidentReply value. +func areTexturesResidentReply(buf []byte) *AreTexturesResidentReply { + v := new(AreTexturesResidentReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = Bool32(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + v.Data = make([]bool, (int(v.Length) * 4)) + for i := 0; i < int((int(v.Length) * 4)); i++ { + if buf[b] == 1 { + v.Data[i] = true + } else { + v.Data[i] = false + } + b += 1 + } + + return v +} + +// Write request to wire for AreTexturesResident +// areTexturesResidentRequest writes a AreTexturesResident request to a byte slice. +func areTexturesResidentRequest(c *xgb.Conn, ContextTag ContextTag, N int32, Textures []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((int(N) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 143 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(N)) + b += 4 + + for i := 0; i < int(N); i++ { + xgb.Put32(buf[b:], Textures[i]) + b += 4 + } + + return buf +} + +// ChangeDrawableAttributesCookie is a cookie used only for ChangeDrawableAttributes requests. +type ChangeDrawableAttributesCookie struct { + *xgb.Cookie +} + +// ChangeDrawableAttributes sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeDrawableAttributes(c *xgb.Conn, Drawable Drawable, NumAttribs uint32, Attribs []uint32) ChangeDrawableAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'ChangeDrawableAttributes' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changeDrawableAttributesRequest(c, Drawable, NumAttribs, Attribs), cookie) + return ChangeDrawableAttributesCookie{cookie} +} + +// ChangeDrawableAttributesChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeDrawableAttributesCookie.Check() +func ChangeDrawableAttributesChecked(c *xgb.Conn, Drawable Drawable, NumAttribs uint32, Attribs []uint32) ChangeDrawableAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'ChangeDrawableAttributes' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changeDrawableAttributesRequest(c, Drawable, NumAttribs, Attribs), cookie) + return ChangeDrawableAttributesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeDrawableAttributesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeDrawableAttributes +// changeDrawableAttributesRequest writes a ChangeDrawableAttributes request to a byte slice. +func changeDrawableAttributesRequest(c *xgb.Conn, Drawable Drawable, NumAttribs uint32, Attribs []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad(((int(NumAttribs) * 2) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 30 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], NumAttribs) + b += 4 + + for i := 0; i < int((int(NumAttribs) * 2)); i++ { + xgb.Put32(buf[b:], Attribs[i]) + b += 4 + } + + return buf +} + +// ClientInfoCookie is a cookie used only for ClientInfo requests. +type ClientInfoCookie struct { + *xgb.Cookie +} + +// ClientInfo sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ClientInfo(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, StrLen uint32, String string) ClientInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'ClientInfo' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(clientInfoRequest(c, MajorVersion, MinorVersion, StrLen, String), cookie) + return ClientInfoCookie{cookie} +} + +// ClientInfoChecked sends a checked request. +// If an error occurs, it can be retrieved using ClientInfoCookie.Check() +func ClientInfoChecked(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, StrLen uint32, String string) ClientInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'ClientInfo' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(clientInfoRequest(c, MajorVersion, MinorVersion, StrLen, String), cookie) + return ClientInfoCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ClientInfoCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ClientInfo +// clientInfoRequest writes a ClientInfo request to a byte slice. +func clientInfoRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, StrLen uint32, String string) []byte { + size := xgb.Pad((16 + xgb.Pad((int(StrLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + xgb.Put32(buf[b:], StrLen) + b += 4 + + copy(buf[b:], String[:StrLen]) + b += int(StrLen) + + return buf +} + +// CopyContextCookie is a cookie used only for CopyContext requests. +type CopyContextCookie struct { + *xgb.Cookie +} + +// CopyContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyContext(c *xgb.Conn, Src Context, Dest Context, Mask uint32, SrcContextTag ContextTag) CopyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CopyContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(copyContextRequest(c, Src, Dest, Mask, SrcContextTag), cookie) + return CopyContextCookie{cookie} +} + +// CopyContextChecked sends a checked request. +// If an error occurs, it can be retrieved using CopyContextCookie.Check() +func CopyContextChecked(c *xgb.Conn, Src Context, Dest Context, Mask uint32, SrcContextTag ContextTag) CopyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CopyContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(copyContextRequest(c, Src, Dest, Mask, SrcContextTag), cookie) + return CopyContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CopyContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CopyContext +// copyContextRequest writes a CopyContext request to a byte slice. +func copyContextRequest(c *xgb.Conn, Src Context, Dest Context, Mask uint32, SrcContextTag ContextTag) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dest)) + b += 4 + + xgb.Put32(buf[b:], Mask) + b += 4 + + xgb.Put32(buf[b:], uint32(SrcContextTag)) + b += 4 + + return buf +} + +// CreateContextCookie is a cookie used only for CreateContext requests. +type CreateContextCookie struct { + *xgb.Cookie +} + +// CreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateContext(c *xgb.Conn, Context Context, Visual xproto.Visualid, Screen uint32, ShareList Context, IsDirect bool) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createContextRequest(c, Context, Visual, Screen, ShareList, IsDirect), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateContextCookie.Check() +func CreateContextChecked(c *xgb.Conn, Context Context, Visual xproto.Visualid, Screen uint32, ShareList Context, IsDirect bool) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createContextRequest(c, Context, Visual, Screen, ShareList, IsDirect), cookie) + return CreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateContext +// createContextRequest writes a CreateContext request to a byte slice. +func createContextRequest(c *xgb.Conn, Context Context, Visual xproto.Visualid, Screen uint32, ShareList Context, IsDirect bool) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], uint32(Visual)) + b += 4 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(ShareList)) + b += 4 + + if IsDirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// CreateContextAttribsARBCookie is a cookie used only for CreateContextAttribsARB requests. +type CreateContextAttribsARBCookie struct { + *xgb.Cookie +} + +// CreateContextAttribsARB sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateContextAttribsARB(c *xgb.Conn, Context Context, Fbconfig Fbconfig, Screen uint32, ShareList Context, IsDirect bool, NumAttribs uint32, Attribs []uint32) CreateContextAttribsARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateContextAttribsARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createContextAttribsARBRequest(c, Context, Fbconfig, Screen, ShareList, IsDirect, NumAttribs, Attribs), cookie) + return CreateContextAttribsARBCookie{cookie} +} + +// CreateContextAttribsARBChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateContextAttribsARBCookie.Check() +func CreateContextAttribsARBChecked(c *xgb.Conn, Context Context, Fbconfig Fbconfig, Screen uint32, ShareList Context, IsDirect bool, NumAttribs uint32, Attribs []uint32) CreateContextAttribsARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateContextAttribsARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createContextAttribsARBRequest(c, Context, Fbconfig, Screen, ShareList, IsDirect, NumAttribs, Attribs), cookie) + return CreateContextAttribsARBCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateContextAttribsARBCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateContextAttribsARB +// createContextAttribsARBRequest writes a CreateContextAttribsARB request to a byte slice. +func createContextAttribsARBRequest(c *xgb.Conn, Context Context, Fbconfig Fbconfig, Screen uint32, ShareList Context, IsDirect bool, NumAttribs uint32, Attribs []uint32) []byte { + size := xgb.Pad((28 + xgb.Pad(((int(NumAttribs) * 2) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 34 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], uint32(Fbconfig)) + b += 4 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(ShareList)) + b += 4 + + if IsDirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], NumAttribs) + b += 4 + + for i := 0; i < int((int(NumAttribs) * 2)); i++ { + xgb.Put32(buf[b:], Attribs[i]) + b += 4 + } + + return buf +} + +// CreateGLXPixmapCookie is a cookie used only for CreateGLXPixmap requests. +type CreateGLXPixmapCookie struct { + *xgb.Cookie +} + +// CreateGLXPixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateGLXPixmap(c *xgb.Conn, Screen uint32, Visual xproto.Visualid, Pixmap xproto.Pixmap, GlxPixmap Pixmap) CreateGLXPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateGLXPixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createGLXPixmapRequest(c, Screen, Visual, Pixmap, GlxPixmap), cookie) + return CreateGLXPixmapCookie{cookie} +} + +// CreateGLXPixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateGLXPixmapCookie.Check() +func CreateGLXPixmapChecked(c *xgb.Conn, Screen uint32, Visual xproto.Visualid, Pixmap xproto.Pixmap, GlxPixmap Pixmap) CreateGLXPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateGLXPixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createGLXPixmapRequest(c, Screen, Visual, Pixmap, GlxPixmap), cookie) + return CreateGLXPixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateGLXPixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateGLXPixmap +// createGLXPixmapRequest writes a CreateGLXPixmap request to a byte slice. +func createGLXPixmapRequest(c *xgb.Conn, Screen uint32, Visual xproto.Visualid, Pixmap xproto.Pixmap, GlxPixmap Pixmap) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Visual)) + b += 4 + + xgb.Put32(buf[b:], uint32(Pixmap)) + b += 4 + + xgb.Put32(buf[b:], uint32(GlxPixmap)) + b += 4 + + return buf +} + +// CreateNewContextCookie is a cookie used only for CreateNewContext requests. +type CreateNewContextCookie struct { + *xgb.Cookie +} + +// CreateNewContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateNewContext(c *xgb.Conn, Context Context, Fbconfig Fbconfig, Screen uint32, RenderType uint32, ShareList Context, IsDirect bool) CreateNewContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateNewContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createNewContextRequest(c, Context, Fbconfig, Screen, RenderType, ShareList, IsDirect), cookie) + return CreateNewContextCookie{cookie} +} + +// CreateNewContextChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateNewContextCookie.Check() +func CreateNewContextChecked(c *xgb.Conn, Context Context, Fbconfig Fbconfig, Screen uint32, RenderType uint32, ShareList Context, IsDirect bool) CreateNewContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateNewContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createNewContextRequest(c, Context, Fbconfig, Screen, RenderType, ShareList, IsDirect), cookie) + return CreateNewContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateNewContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateNewContext +// createNewContextRequest writes a CreateNewContext request to a byte slice. +func createNewContextRequest(c *xgb.Conn, Context Context, Fbconfig Fbconfig, Screen uint32, RenderType uint32, ShareList Context, IsDirect bool) []byte { + size := 28 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 24 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], uint32(Fbconfig)) + b += 4 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], RenderType) + b += 4 + + xgb.Put32(buf[b:], uint32(ShareList)) + b += 4 + + if IsDirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// CreatePbufferCookie is a cookie used only for CreatePbuffer requests. +type CreatePbufferCookie struct { + *xgb.Cookie +} + +// CreatePbuffer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreatePbuffer(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Pbuffer Pbuffer, NumAttribs uint32, Attribs []uint32) CreatePbufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreatePbuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createPbufferRequest(c, Screen, Fbconfig, Pbuffer, NumAttribs, Attribs), cookie) + return CreatePbufferCookie{cookie} +} + +// CreatePbufferChecked sends a checked request. +// If an error occurs, it can be retrieved using CreatePbufferCookie.Check() +func CreatePbufferChecked(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Pbuffer Pbuffer, NumAttribs uint32, Attribs []uint32) CreatePbufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreatePbuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createPbufferRequest(c, Screen, Fbconfig, Pbuffer, NumAttribs, Attribs), cookie) + return CreatePbufferCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreatePbufferCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreatePbuffer +// createPbufferRequest writes a CreatePbuffer request to a byte slice. +func createPbufferRequest(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Pbuffer Pbuffer, NumAttribs uint32, Attribs []uint32) []byte { + size := xgb.Pad((20 + xgb.Pad(((int(NumAttribs) * 2) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 27 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Fbconfig)) + b += 4 + + xgb.Put32(buf[b:], uint32(Pbuffer)) + b += 4 + + xgb.Put32(buf[b:], NumAttribs) + b += 4 + + for i := 0; i < int((int(NumAttribs) * 2)); i++ { + xgb.Put32(buf[b:], Attribs[i]) + b += 4 + } + + return buf +} + +// CreatePixmapCookie is a cookie used only for CreatePixmap requests. +type CreatePixmapCookie struct { + *xgb.Cookie +} + +// CreatePixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreatePixmap(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Pixmap xproto.Pixmap, GlxPixmap Pixmap, NumAttribs uint32, Attribs []uint32) CreatePixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createPixmapRequest(c, Screen, Fbconfig, Pixmap, GlxPixmap, NumAttribs, Attribs), cookie) + return CreatePixmapCookie{cookie} +} + +// CreatePixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using CreatePixmapCookie.Check() +func CreatePixmapChecked(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Pixmap xproto.Pixmap, GlxPixmap Pixmap, NumAttribs uint32, Attribs []uint32) CreatePixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createPixmapRequest(c, Screen, Fbconfig, Pixmap, GlxPixmap, NumAttribs, Attribs), cookie) + return CreatePixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreatePixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreatePixmap +// createPixmapRequest writes a CreatePixmap request to a byte slice. +func createPixmapRequest(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Pixmap xproto.Pixmap, GlxPixmap Pixmap, NumAttribs uint32, Attribs []uint32) []byte { + size := xgb.Pad((24 + xgb.Pad(((int(NumAttribs) * 2) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 22 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Fbconfig)) + b += 4 + + xgb.Put32(buf[b:], uint32(Pixmap)) + b += 4 + + xgb.Put32(buf[b:], uint32(GlxPixmap)) + b += 4 + + xgb.Put32(buf[b:], NumAttribs) + b += 4 + + for i := 0; i < int((int(NumAttribs) * 2)); i++ { + xgb.Put32(buf[b:], Attribs[i]) + b += 4 + } + + return buf +} + +// CreateWindowCookie is a cookie used only for CreateWindow requests. +type CreateWindowCookie struct { + *xgb.Cookie +} + +// CreateWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateWindow(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Window xproto.Window, GlxWindow Window, NumAttribs uint32, Attribs []uint32) CreateWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateWindow' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createWindowRequest(c, Screen, Fbconfig, Window, GlxWindow, NumAttribs, Attribs), cookie) + return CreateWindowCookie{cookie} +} + +// CreateWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateWindowCookie.Check() +func CreateWindowChecked(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Window xproto.Window, GlxWindow Window, NumAttribs uint32, Attribs []uint32) CreateWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'CreateWindow' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createWindowRequest(c, Screen, Fbconfig, Window, GlxWindow, NumAttribs, Attribs), cookie) + return CreateWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateWindow +// createWindowRequest writes a CreateWindow request to a byte slice. +func createWindowRequest(c *xgb.Conn, Screen uint32, Fbconfig Fbconfig, Window xproto.Window, GlxWindow Window, NumAttribs uint32, Attribs []uint32) []byte { + size := xgb.Pad((24 + xgb.Pad(((int(NumAttribs) * 2) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 31 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Fbconfig)) + b += 4 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(GlxWindow)) + b += 4 + + xgb.Put32(buf[b:], NumAttribs) + b += 4 + + for i := 0; i < int((int(NumAttribs) * 2)); i++ { + xgb.Put32(buf[b:], Attribs[i]) + b += 4 + } + + return buf +} + +// DeleteListsCookie is a cookie used only for DeleteLists requests. +type DeleteListsCookie struct { + *xgb.Cookie +} + +// DeleteLists sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteLists(c *xgb.Conn, ContextTag ContextTag, List uint32, Range int32) DeleteListsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteLists' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteListsRequest(c, ContextTag, List, Range), cookie) + return DeleteListsCookie{cookie} +} + +// DeleteListsChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteListsCookie.Check() +func DeleteListsChecked(c *xgb.Conn, ContextTag ContextTag, List uint32, Range int32) DeleteListsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteLists' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteListsRequest(c, ContextTag, List, Range), cookie) + return DeleteListsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteListsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteLists +// deleteListsRequest writes a DeleteLists request to a byte slice. +func deleteListsRequest(c *xgb.Conn, ContextTag ContextTag, List uint32, Range int32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 103 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], List) + b += 4 + + xgb.Put32(buf[b:], uint32(Range)) + b += 4 + + return buf +} + +// DeleteQueriesARBCookie is a cookie used only for DeleteQueriesARB requests. +type DeleteQueriesARBCookie struct { + *xgb.Cookie +} + +// DeleteQueriesARB sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteQueriesARB(c *xgb.Conn, ContextTag ContextTag, N int32, Ids []uint32) DeleteQueriesARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteQueriesARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteQueriesARBRequest(c, ContextTag, N, Ids), cookie) + return DeleteQueriesARBCookie{cookie} +} + +// DeleteQueriesARBChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteQueriesARBCookie.Check() +func DeleteQueriesARBChecked(c *xgb.Conn, ContextTag ContextTag, N int32, Ids []uint32) DeleteQueriesARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteQueriesARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteQueriesARBRequest(c, ContextTag, N, Ids), cookie) + return DeleteQueriesARBCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteQueriesARBCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteQueriesARB +// deleteQueriesARBRequest writes a DeleteQueriesARB request to a byte slice. +func deleteQueriesARBRequest(c *xgb.Conn, ContextTag ContextTag, N int32, Ids []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((int(N) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 161 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(N)) + b += 4 + + for i := 0; i < int(N); i++ { + xgb.Put32(buf[b:], Ids[i]) + b += 4 + } + + return buf +} + +// DeleteTexturesCookie is a cookie used only for DeleteTextures requests. +type DeleteTexturesCookie struct { + *xgb.Cookie +} + +// DeleteTextures sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteTextures(c *xgb.Conn, ContextTag ContextTag, N int32, Textures []uint32) DeleteTexturesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteTextures' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteTexturesRequest(c, ContextTag, N, Textures), cookie) + return DeleteTexturesCookie{cookie} +} + +// DeleteTexturesChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteTexturesCookie.Check() +func DeleteTexturesChecked(c *xgb.Conn, ContextTag ContextTag, N int32, Textures []uint32) DeleteTexturesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteTextures' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteTexturesRequest(c, ContextTag, N, Textures), cookie) + return DeleteTexturesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteTexturesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteTextures +// deleteTexturesRequest writes a DeleteTextures request to a byte slice. +func deleteTexturesRequest(c *xgb.Conn, ContextTag ContextTag, N int32, Textures []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((int(N) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 144 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(N)) + b += 4 + + for i := 0; i < int(N); i++ { + xgb.Put32(buf[b:], Textures[i]) + b += 4 + } + + return buf +} + +// DeleteWindowCookie is a cookie used only for DeleteWindow requests. +type DeleteWindowCookie struct { + *xgb.Cookie +} + +// DeleteWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteWindow(c *xgb.Conn, Glxwindow Window) DeleteWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteWindow' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteWindowRequest(c, Glxwindow), cookie) + return DeleteWindowCookie{cookie} +} + +// DeleteWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteWindowCookie.Check() +func DeleteWindowChecked(c *xgb.Conn, Glxwindow Window) DeleteWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DeleteWindow' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteWindowRequest(c, Glxwindow), cookie) + return DeleteWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteWindow +// deleteWindowRequest writes a DeleteWindow request to a byte slice. +func deleteWindowRequest(c *xgb.Conn, Glxwindow Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 32 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Glxwindow)) + b += 4 + + return buf +} + +// DestroyContextCookie is a cookie used only for DestroyContext requests. +type DestroyContextCookie struct { + *xgb.Cookie +} + +// DestroyContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyContext(c *xgb.Conn, Context Context) DestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyContextRequest(c, Context), cookie) + return DestroyContextCookie{cookie} +} + +// DestroyContextChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyContextCookie.Check() +func DestroyContextChecked(c *xgb.Conn, Context Context) DestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyContextRequest(c, Context), cookie) + return DestroyContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyContext +// destroyContextRequest writes a DestroyContext request to a byte slice. +func destroyContextRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// DestroyGLXPixmapCookie is a cookie used only for DestroyGLXPixmap requests. +type DestroyGLXPixmapCookie struct { + *xgb.Cookie +} + +// DestroyGLXPixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyGLXPixmap(c *xgb.Conn, GlxPixmap Pixmap) DestroyGLXPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyGLXPixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyGLXPixmapRequest(c, GlxPixmap), cookie) + return DestroyGLXPixmapCookie{cookie} +} + +// DestroyGLXPixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyGLXPixmapCookie.Check() +func DestroyGLXPixmapChecked(c *xgb.Conn, GlxPixmap Pixmap) DestroyGLXPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyGLXPixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyGLXPixmapRequest(c, GlxPixmap), cookie) + return DestroyGLXPixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyGLXPixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyGLXPixmap +// destroyGLXPixmapRequest writes a DestroyGLXPixmap request to a byte slice. +func destroyGLXPixmapRequest(c *xgb.Conn, GlxPixmap Pixmap) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GlxPixmap)) + b += 4 + + return buf +} + +// DestroyPbufferCookie is a cookie used only for DestroyPbuffer requests. +type DestroyPbufferCookie struct { + *xgb.Cookie +} + +// DestroyPbuffer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyPbuffer(c *xgb.Conn, Pbuffer Pbuffer) DestroyPbufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyPbuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyPbufferRequest(c, Pbuffer), cookie) + return DestroyPbufferCookie{cookie} +} + +// DestroyPbufferChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyPbufferCookie.Check() +func DestroyPbufferChecked(c *xgb.Conn, Pbuffer Pbuffer) DestroyPbufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyPbuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyPbufferRequest(c, Pbuffer), cookie) + return DestroyPbufferCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyPbufferCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyPbuffer +// destroyPbufferRequest writes a DestroyPbuffer request to a byte slice. +func destroyPbufferRequest(c *xgb.Conn, Pbuffer Pbuffer) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 28 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Pbuffer)) + b += 4 + + return buf +} + +// DestroyPixmapCookie is a cookie used only for DestroyPixmap requests. +type DestroyPixmapCookie struct { + *xgb.Cookie +} + +// DestroyPixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyPixmap(c *xgb.Conn, GlxPixmap Pixmap) DestroyPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyPixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyPixmapRequest(c, GlxPixmap), cookie) + return DestroyPixmapCookie{cookie} +} + +// DestroyPixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyPixmapCookie.Check() +func DestroyPixmapChecked(c *xgb.Conn, GlxPixmap Pixmap) DestroyPixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'DestroyPixmap' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyPixmapRequest(c, GlxPixmap), cookie) + return DestroyPixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyPixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyPixmap +// destroyPixmapRequest writes a DestroyPixmap request to a byte slice. +func destroyPixmapRequest(c *xgb.Conn, GlxPixmap Pixmap) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 23 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GlxPixmap)) + b += 4 + + return buf +} + +// EndListCookie is a cookie used only for EndList requests. +type EndListCookie struct { + *xgb.Cookie +} + +// EndList sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func EndList(c *xgb.Conn, ContextTag ContextTag) EndListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'EndList' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(endListRequest(c, ContextTag), cookie) + return EndListCookie{cookie} +} + +// EndListChecked sends a checked request. +// If an error occurs, it can be retrieved using EndListCookie.Check() +func EndListChecked(c *xgb.Conn, ContextTag ContextTag) EndListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'EndList' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(endListRequest(c, ContextTag), cookie) + return EndListCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook EndListCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for EndList +// endListRequest writes a EndList request to a byte slice. +func endListRequest(c *xgb.Conn, ContextTag ContextTag) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 102 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + return buf +} + +// FeedbackBufferCookie is a cookie used only for FeedbackBuffer requests. +type FeedbackBufferCookie struct { + *xgb.Cookie +} + +// FeedbackBuffer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FeedbackBuffer(c *xgb.Conn, ContextTag ContextTag, Size int32, Type int32) FeedbackBufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'FeedbackBuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(feedbackBufferRequest(c, ContextTag, Size, Type), cookie) + return FeedbackBufferCookie{cookie} +} + +// FeedbackBufferChecked sends a checked request. +// If an error occurs, it can be retrieved using FeedbackBufferCookie.Check() +func FeedbackBufferChecked(c *xgb.Conn, ContextTag ContextTag, Size int32, Type int32) FeedbackBufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'FeedbackBuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(feedbackBufferRequest(c, ContextTag, Size, Type), cookie) + return FeedbackBufferCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FeedbackBufferCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FeedbackBuffer +// feedbackBufferRequest writes a FeedbackBuffer request to a byte slice. +func feedbackBufferRequest(c *xgb.Conn, ContextTag ContextTag, Size int32, Type int32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 105 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Size)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + return buf +} + +// FinishCookie is a cookie used only for Finish requests. +type FinishCookie struct { + *xgb.Cookie +} + +// Finish sends a checked request. +// If an error occurs, it will be returned with the reply by calling FinishCookie.Reply() +func Finish(c *xgb.Conn, ContextTag ContextTag) FinishCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'Finish' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(finishRequest(c, ContextTag), cookie) + return FinishCookie{cookie} +} + +// FinishUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FinishUnchecked(c *xgb.Conn, ContextTag ContextTag) FinishCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'Finish' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(finishRequest(c, ContextTag), cookie) + return FinishCookie{cookie} +} + +// FinishReply represents the data returned from a Finish request. +type FinishReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes +} + +// Reply blocks and returns the reply data for a Finish request. +func (cook FinishCookie) Reply() (*FinishReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return finishReply(buf), nil +} + +// finishReply reads a byte slice into a FinishReply value. +func finishReply(buf []byte) *FinishReply { + v := new(FinishReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for Finish +// finishRequest writes a Finish request to a byte slice. +func finishRequest(c *xgb.Conn, ContextTag ContextTag) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 108 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + return buf +} + +// FlushCookie is a cookie used only for Flush requests. +type FlushCookie struct { + *xgb.Cookie +} + +// Flush sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Flush(c *xgb.Conn, ContextTag ContextTag) FlushCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'Flush' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(flushRequest(c, ContextTag), cookie) + return FlushCookie{cookie} +} + +// FlushChecked sends a checked request. +// If an error occurs, it can be retrieved using FlushCookie.Check() +func FlushChecked(c *xgb.Conn, ContextTag ContextTag) FlushCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'Flush' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(flushRequest(c, ContextTag), cookie) + return FlushCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FlushCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Flush +// flushRequest writes a Flush request to a byte slice. +func flushRequest(c *xgb.Conn, ContextTag ContextTag) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 142 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + return buf +} + +// GenListsCookie is a cookie used only for GenLists requests. +type GenListsCookie struct { + *xgb.Cookie +} + +// GenLists sends a checked request. +// If an error occurs, it will be returned with the reply by calling GenListsCookie.Reply() +func GenLists(c *xgb.Conn, ContextTag ContextTag, Range int32) GenListsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GenLists' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(genListsRequest(c, ContextTag, Range), cookie) + return GenListsCookie{cookie} +} + +// GenListsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GenListsUnchecked(c *xgb.Conn, ContextTag ContextTag, Range int32) GenListsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GenLists' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(genListsRequest(c, ContextTag, Range), cookie) + return GenListsCookie{cookie} +} + +// GenListsReply represents the data returned from a GenLists request. +type GenListsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal uint32 +} + +// Reply blocks and returns the reply data for a GenLists request. +func (cook GenListsCookie) Reply() (*GenListsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return genListsReply(buf), nil +} + +// genListsReply reads a byte slice into a GenListsReply value. +func genListsReply(buf []byte) *GenListsReply { + v := new(GenListsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GenLists +// genListsRequest writes a GenLists request to a byte slice. +func genListsRequest(c *xgb.Conn, ContextTag ContextTag, Range int32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 104 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Range)) + b += 4 + + return buf +} + +// GenQueriesARBCookie is a cookie used only for GenQueriesARB requests. +type GenQueriesARBCookie struct { + *xgb.Cookie +} + +// GenQueriesARB sends a checked request. +// If an error occurs, it will be returned with the reply by calling GenQueriesARBCookie.Reply() +func GenQueriesARB(c *xgb.Conn, ContextTag ContextTag, N int32) GenQueriesARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GenQueriesARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(genQueriesARBRequest(c, ContextTag, N), cookie) + return GenQueriesARBCookie{cookie} +} + +// GenQueriesARBUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GenQueriesARBUnchecked(c *xgb.Conn, ContextTag ContextTag, N int32) GenQueriesARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GenQueriesARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(genQueriesARBRequest(c, ContextTag, N), cookie) + return GenQueriesARBCookie{cookie} +} + +// GenQueriesARBReply represents the data returned from a GenQueriesARB request. +type GenQueriesARBReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + Data []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a GenQueriesARB request. +func (cook GenQueriesARBCookie) Reply() (*GenQueriesARBReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return genQueriesARBReply(buf), nil +} + +// genQueriesARBReply reads a byte slice into a GenQueriesARBReply value. +func genQueriesARBReply(buf []byte) *GenQueriesARBReply { + v := new(GenQueriesARBReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Data = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.Data[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GenQueriesARB +// genQueriesARBRequest writes a GenQueriesARB request to a byte slice. +func genQueriesARBRequest(c *xgb.Conn, ContextTag ContextTag, N int32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 162 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(N)) + b += 4 + + return buf +} + +// GenTexturesCookie is a cookie used only for GenTextures requests. +type GenTexturesCookie struct { + *xgb.Cookie +} + +// GenTextures sends a checked request. +// If an error occurs, it will be returned with the reply by calling GenTexturesCookie.Reply() +func GenTextures(c *xgb.Conn, ContextTag ContextTag, N int32) GenTexturesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GenTextures' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(genTexturesRequest(c, ContextTag, N), cookie) + return GenTexturesCookie{cookie} +} + +// GenTexturesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GenTexturesUnchecked(c *xgb.Conn, ContextTag ContextTag, N int32) GenTexturesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GenTextures' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(genTexturesRequest(c, ContextTag, N), cookie) + return GenTexturesCookie{cookie} +} + +// GenTexturesReply represents the data returned from a GenTextures request. +type GenTexturesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + Data []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a GenTextures request. +func (cook GenTexturesCookie) Reply() (*GenTexturesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return genTexturesReply(buf), nil +} + +// genTexturesReply reads a byte slice into a GenTexturesReply value. +func genTexturesReply(buf []byte) *GenTexturesReply { + v := new(GenTexturesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Data = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.Data[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GenTextures +// genTexturesRequest writes a GenTextures request to a byte slice. +func genTexturesRequest(c *xgb.Conn, ContextTag ContextTag, N int32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 145 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(N)) + b += 4 + + return buf +} + +// GetBooleanvCookie is a cookie used only for GetBooleanv requests. +type GetBooleanvCookie struct { + *xgb.Cookie +} + +// GetBooleanv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetBooleanvCookie.Reply() +func GetBooleanv(c *xgb.Conn, ContextTag ContextTag, Pname int32) GetBooleanvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetBooleanv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getBooleanvRequest(c, ContextTag, Pname), cookie) + return GetBooleanvCookie{cookie} +} + +// GetBooleanvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetBooleanvUnchecked(c *xgb.Conn, ContextTag ContextTag, Pname int32) GetBooleanvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetBooleanv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getBooleanvRequest(c, ContextTag, Pname), cookie) + return GetBooleanvCookie{cookie} +} + +// GetBooleanvReply represents the data returned from a GetBooleanv request. +type GetBooleanvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum bool + // padding: 15 bytes + Data []bool // size: xgb.Pad((int(N) * 1)) +} + +// Reply blocks and returns the reply data for a GetBooleanv request. +func (cook GetBooleanvCookie) Reply() (*GetBooleanvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getBooleanvReply(buf), nil +} + +// getBooleanvReply reads a byte slice into a GetBooleanvReply value. +func getBooleanvReply(buf []byte) *GetBooleanvReply { + v := new(GetBooleanvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + if buf[b] == 1 { + v.Datum = true + } else { + v.Datum = false + } + b += 1 + + b += 15 // padding + + v.Data = make([]bool, v.N) + for i := 0; i < int(v.N); i++ { + if buf[b] == 1 { + v.Data[i] = true + } else { + v.Data[i] = false + } + b += 1 + } + + return v +} + +// Write request to wire for GetBooleanv +// getBooleanvRequest writes a GetBooleanv request to a byte slice. +func getBooleanvRequest(c *xgb.Conn, ContextTag ContextTag, Pname int32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 112 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Pname)) + b += 4 + + return buf +} + +// GetClipPlaneCookie is a cookie used only for GetClipPlane requests. +type GetClipPlaneCookie struct { + *xgb.Cookie +} + +// GetClipPlane sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetClipPlaneCookie.Reply() +func GetClipPlane(c *xgb.Conn, ContextTag ContextTag, Plane int32) GetClipPlaneCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetClipPlane' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getClipPlaneRequest(c, ContextTag, Plane), cookie) + return GetClipPlaneCookie{cookie} +} + +// GetClipPlaneUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetClipPlaneUnchecked(c *xgb.Conn, ContextTag ContextTag, Plane int32) GetClipPlaneCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetClipPlane' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getClipPlaneRequest(c, ContextTag, Plane), cookie) + return GetClipPlaneCookie{cookie} +} + +// GetClipPlaneReply represents the data returned from a GetClipPlane request. +type GetClipPlaneReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + Data []Float64 // size: xgb.Pad(((int(Length) / 2) * 8)) +} + +// Reply blocks and returns the reply data for a GetClipPlane request. +func (cook GetClipPlaneCookie) Reply() (*GetClipPlaneReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getClipPlaneReply(buf), nil +} + +// getClipPlaneReply reads a byte slice into a GetClipPlaneReply value. +func getClipPlaneReply(buf []byte) *GetClipPlaneReply { + v := new(GetClipPlaneReply) + b := 1 // skip reply determinant + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 1 // padding + + b += 24 // padding + + v.Data = make([]Float64, (int(v.Length) / 2)) + for i := 0; i < int((int(v.Length) / 2)); i++ { + v.Data[i] = Float64(xgb.Get64(buf[b:])) + b += 8 + } + + return v +} + +// Write request to wire for GetClipPlane +// getClipPlaneRequest writes a GetClipPlane request to a byte slice. +func getClipPlaneRequest(c *xgb.Conn, ContextTag ContextTag, Plane int32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 113 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Plane)) + b += 4 + + return buf +} + +// GetColorTableCookie is a cookie used only for GetColorTable requests. +type GetColorTableCookie struct { + *xgb.Cookie +} + +// GetColorTable sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetColorTableCookie.Reply() +func GetColorTable(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) GetColorTableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetColorTable' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getColorTableRequest(c, ContextTag, Target, Format, Type, SwapBytes), cookie) + return GetColorTableCookie{cookie} +} + +// GetColorTableUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetColorTableUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) GetColorTableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetColorTable' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getColorTableRequest(c, ContextTag, Target, Format, Type, SwapBytes), cookie) + return GetColorTableCookie{cookie} +} + +// GetColorTableReply represents the data returned from a GetColorTable request. +type GetColorTableReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 8 bytes + Width int32 + // padding: 12 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetColorTable request. +func (cook GetColorTableCookie) Reply() (*GetColorTableReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getColorTableReply(buf), nil +} + +// getColorTableReply reads a byte slice into a GetColorTableReply value. +func getColorTableReply(buf []byte) *GetColorTableReply { + v := new(GetColorTableReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 8 // padding + + v.Width = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetColorTable +// getColorTableRequest writes a GetColorTable request to a byte slice. +func getColorTableRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 147 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetColorTableParameterfvCookie is a cookie used only for GetColorTableParameterfv requests. +type GetColorTableParameterfvCookie struct { + *xgb.Cookie +} + +// GetColorTableParameterfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetColorTableParameterfvCookie.Reply() +func GetColorTableParameterfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetColorTableParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetColorTableParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getColorTableParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetColorTableParameterfvCookie{cookie} +} + +// GetColorTableParameterfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetColorTableParameterfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetColorTableParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetColorTableParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getColorTableParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetColorTableParameterfvCookie{cookie} +} + +// GetColorTableParameterfvReply represents the data returned from a GetColorTableParameterfv request. +type GetColorTableParameterfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetColorTableParameterfv request. +func (cook GetColorTableParameterfvCookie) Reply() (*GetColorTableParameterfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getColorTableParameterfvReply(buf), nil +} + +// getColorTableParameterfvReply reads a byte slice into a GetColorTableParameterfvReply value. +func getColorTableParameterfvReply(buf []byte) *GetColorTableParameterfvReply { + v := new(GetColorTableParameterfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetColorTableParameterfv +// getColorTableParameterfvRequest writes a GetColorTableParameterfv request to a byte slice. +func getColorTableParameterfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 148 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetColorTableParameterivCookie is a cookie used only for GetColorTableParameteriv requests. +type GetColorTableParameterivCookie struct { + *xgb.Cookie +} + +// GetColorTableParameteriv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetColorTableParameterivCookie.Reply() +func GetColorTableParameteriv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetColorTableParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetColorTableParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getColorTableParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetColorTableParameterivCookie{cookie} +} + +// GetColorTableParameterivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetColorTableParameterivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetColorTableParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetColorTableParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getColorTableParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetColorTableParameterivCookie{cookie} +} + +// GetColorTableParameterivReply represents the data returned from a GetColorTableParameteriv request. +type GetColorTableParameterivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetColorTableParameteriv request. +func (cook GetColorTableParameterivCookie) Reply() (*GetColorTableParameterivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getColorTableParameterivReply(buf), nil +} + +// getColorTableParameterivReply reads a byte slice into a GetColorTableParameterivReply value. +func getColorTableParameterivReply(buf []byte) *GetColorTableParameterivReply { + v := new(GetColorTableParameterivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetColorTableParameteriv +// getColorTableParameterivRequest writes a GetColorTableParameteriv request to a byte slice. +func getColorTableParameterivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 149 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetCompressedTexImageARBCookie is a cookie used only for GetCompressedTexImageARB requests. +type GetCompressedTexImageARBCookie struct { + *xgb.Cookie +} + +// GetCompressedTexImageARB sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCompressedTexImageARBCookie.Reply() +func GetCompressedTexImageARB(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32) GetCompressedTexImageARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetCompressedTexImageARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCompressedTexImageARBRequest(c, ContextTag, Target, Level), cookie) + return GetCompressedTexImageARBCookie{cookie} +} + +// GetCompressedTexImageARBUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCompressedTexImageARBUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32) GetCompressedTexImageARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetCompressedTexImageARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCompressedTexImageARBRequest(c, ContextTag, Target, Level), cookie) + return GetCompressedTexImageARBCookie{cookie} +} + +// GetCompressedTexImageARBReply represents the data returned from a GetCompressedTexImageARB request. +type GetCompressedTexImageARBReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 8 bytes + Size int32 + // padding: 12 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetCompressedTexImageARB request. +func (cook GetCompressedTexImageARBCookie) Reply() (*GetCompressedTexImageARBReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCompressedTexImageARBReply(buf), nil +} + +// getCompressedTexImageARBReply reads a byte slice into a GetCompressedTexImageARBReply value. +func getCompressedTexImageARBReply(buf []byte) *GetCompressedTexImageARBReply { + v := new(GetCompressedTexImageARBReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 8 // padding + + v.Size = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetCompressedTexImageARB +// getCompressedTexImageARBRequest writes a GetCompressedTexImageARB request to a byte slice. +func getCompressedTexImageARBRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 160 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], uint32(Level)) + b += 4 + + return buf +} + +// GetConvolutionFilterCookie is a cookie used only for GetConvolutionFilter requests. +type GetConvolutionFilterCookie struct { + *xgb.Cookie +} + +// GetConvolutionFilter sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetConvolutionFilterCookie.Reply() +func GetConvolutionFilter(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) GetConvolutionFilterCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetConvolutionFilter' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getConvolutionFilterRequest(c, ContextTag, Target, Format, Type, SwapBytes), cookie) + return GetConvolutionFilterCookie{cookie} +} + +// GetConvolutionFilterUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetConvolutionFilterUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) GetConvolutionFilterCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetConvolutionFilter' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getConvolutionFilterRequest(c, ContextTag, Target, Format, Type, SwapBytes), cookie) + return GetConvolutionFilterCookie{cookie} +} + +// GetConvolutionFilterReply represents the data returned from a GetConvolutionFilter request. +type GetConvolutionFilterReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 8 bytes + Width int32 + Height int32 + // padding: 8 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetConvolutionFilter request. +func (cook GetConvolutionFilterCookie) Reply() (*GetConvolutionFilterReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getConvolutionFilterReply(buf), nil +} + +// getConvolutionFilterReply reads a byte slice into a GetConvolutionFilterReply value. +func getConvolutionFilterReply(buf []byte) *GetConvolutionFilterReply { + v := new(GetConvolutionFilterReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 8 // padding + + v.Width = int32(xgb.Get32(buf[b:])) + b += 4 + + v.Height = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 8 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetConvolutionFilter +// getConvolutionFilterRequest writes a GetConvolutionFilter request to a byte slice. +func getConvolutionFilterRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 150 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetConvolutionParameterfvCookie is a cookie used only for GetConvolutionParameterfv requests. +type GetConvolutionParameterfvCookie struct { + *xgb.Cookie +} + +// GetConvolutionParameterfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetConvolutionParameterfvCookie.Reply() +func GetConvolutionParameterfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetConvolutionParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetConvolutionParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getConvolutionParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetConvolutionParameterfvCookie{cookie} +} + +// GetConvolutionParameterfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetConvolutionParameterfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetConvolutionParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetConvolutionParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getConvolutionParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetConvolutionParameterfvCookie{cookie} +} + +// GetConvolutionParameterfvReply represents the data returned from a GetConvolutionParameterfv request. +type GetConvolutionParameterfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetConvolutionParameterfv request. +func (cook GetConvolutionParameterfvCookie) Reply() (*GetConvolutionParameterfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getConvolutionParameterfvReply(buf), nil +} + +// getConvolutionParameterfvReply reads a byte slice into a GetConvolutionParameterfvReply value. +func getConvolutionParameterfvReply(buf []byte) *GetConvolutionParameterfvReply { + v := new(GetConvolutionParameterfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetConvolutionParameterfv +// getConvolutionParameterfvRequest writes a GetConvolutionParameterfv request to a byte slice. +func getConvolutionParameterfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 151 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetConvolutionParameterivCookie is a cookie used only for GetConvolutionParameteriv requests. +type GetConvolutionParameterivCookie struct { + *xgb.Cookie +} + +// GetConvolutionParameteriv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetConvolutionParameterivCookie.Reply() +func GetConvolutionParameteriv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetConvolutionParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetConvolutionParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getConvolutionParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetConvolutionParameterivCookie{cookie} +} + +// GetConvolutionParameterivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetConvolutionParameterivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetConvolutionParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetConvolutionParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getConvolutionParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetConvolutionParameterivCookie{cookie} +} + +// GetConvolutionParameterivReply represents the data returned from a GetConvolutionParameteriv request. +type GetConvolutionParameterivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetConvolutionParameteriv request. +func (cook GetConvolutionParameterivCookie) Reply() (*GetConvolutionParameterivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getConvolutionParameterivReply(buf), nil +} + +// getConvolutionParameterivReply reads a byte slice into a GetConvolutionParameterivReply value. +func getConvolutionParameterivReply(buf []byte) *GetConvolutionParameterivReply { + v := new(GetConvolutionParameterivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetConvolutionParameteriv +// getConvolutionParameterivRequest writes a GetConvolutionParameteriv request to a byte slice. +func getConvolutionParameterivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 152 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetDoublevCookie is a cookie used only for GetDoublev requests. +type GetDoublevCookie struct { + *xgb.Cookie +} + +// GetDoublev sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDoublevCookie.Reply() +func GetDoublev(c *xgb.Conn, ContextTag ContextTag, Pname uint32) GetDoublevCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetDoublev' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDoublevRequest(c, ContextTag, Pname), cookie) + return GetDoublevCookie{cookie} +} + +// GetDoublevUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDoublevUnchecked(c *xgb.Conn, ContextTag ContextTag, Pname uint32) GetDoublevCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetDoublev' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDoublevRequest(c, ContextTag, Pname), cookie) + return GetDoublevCookie{cookie} +} + +// GetDoublevReply represents the data returned from a GetDoublev request. +type GetDoublevReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float64 + // padding: 8 bytes + Data []Float64 // size: xgb.Pad((int(N) * 8)) +} + +// Reply blocks and returns the reply data for a GetDoublev request. +func (cook GetDoublevCookie) Reply() (*GetDoublevReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDoublevReply(buf), nil +} + +// getDoublevReply reads a byte slice into a GetDoublevReply value. +func getDoublevReply(buf []byte) *GetDoublevReply { + v := new(GetDoublevReply) + b := 1 // skip reply determinant + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 1 // padding + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float64(xgb.Get64(buf[b:])) + b += 8 + + b += 8 // padding + + v.Data = make([]Float64, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float64(xgb.Get64(buf[b:])) + b += 8 + } + + return v +} + +// Write request to wire for GetDoublev +// getDoublevRequest writes a GetDoublev request to a byte slice. +func getDoublevRequest(c *xgb.Conn, ContextTag ContextTag, Pname uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 114 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetDrawableAttributesCookie is a cookie used only for GetDrawableAttributes requests. +type GetDrawableAttributesCookie struct { + *xgb.Cookie +} + +// GetDrawableAttributes sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDrawableAttributesCookie.Reply() +func GetDrawableAttributes(c *xgb.Conn, Drawable Drawable) GetDrawableAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetDrawableAttributes' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDrawableAttributesRequest(c, Drawable), cookie) + return GetDrawableAttributesCookie{cookie} +} + +// GetDrawableAttributesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDrawableAttributesUnchecked(c *xgb.Conn, Drawable Drawable) GetDrawableAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetDrawableAttributes' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDrawableAttributesRequest(c, Drawable), cookie) + return GetDrawableAttributesCookie{cookie} +} + +// GetDrawableAttributesReply represents the data returned from a GetDrawableAttributes request. +type GetDrawableAttributesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAttribs uint32 + // padding: 20 bytes + Attribs []uint32 // size: xgb.Pad(((int(NumAttribs) * 2) * 4)) +} + +// Reply blocks and returns the reply data for a GetDrawableAttributes request. +func (cook GetDrawableAttributesCookie) Reply() (*GetDrawableAttributesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDrawableAttributesReply(buf), nil +} + +// getDrawableAttributesReply reads a byte slice into a GetDrawableAttributesReply value. +func getDrawableAttributesReply(buf []byte) *GetDrawableAttributesReply { + v := new(GetDrawableAttributesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAttribs = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Attribs = make([]uint32, (int(v.NumAttribs) * 2)) + for i := 0; i < int((int(v.NumAttribs) * 2)); i++ { + v.Attribs[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetDrawableAttributes +// getDrawableAttributesRequest writes a GetDrawableAttributes request to a byte slice. +func getDrawableAttributesRequest(c *xgb.Conn, Drawable Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 29 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// GetErrorCookie is a cookie used only for GetError requests. +type GetErrorCookie struct { + *xgb.Cookie +} + +// GetError sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetErrorCookie.Reply() +func GetError(c *xgb.Conn, ContextTag ContextTag) GetErrorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetError' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getErrorRequest(c, ContextTag), cookie) + return GetErrorCookie{cookie} +} + +// GetErrorUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetErrorUnchecked(c *xgb.Conn, ContextTag ContextTag) GetErrorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetError' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getErrorRequest(c, ContextTag), cookie) + return GetErrorCookie{cookie} +} + +// GetErrorReply represents the data returned from a GetError request. +type GetErrorReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Error int32 +} + +// Reply blocks and returns the reply data for a GetError request. +func (cook GetErrorCookie) Reply() (*GetErrorReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getErrorReply(buf), nil +} + +// getErrorReply reads a byte slice into a GetErrorReply value. +func getErrorReply(buf []byte) *GetErrorReply { + v := new(GetErrorReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Error = int32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetError +// getErrorRequest writes a GetError request to a byte slice. +func getErrorRequest(c *xgb.Conn, ContextTag ContextTag) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 115 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + return buf +} + +// GetFBConfigsCookie is a cookie used only for GetFBConfigs requests. +type GetFBConfigsCookie struct { + *xgb.Cookie +} + +// GetFBConfigs sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetFBConfigsCookie.Reply() +func GetFBConfigs(c *xgb.Conn, Screen uint32) GetFBConfigsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetFBConfigs' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getFBConfigsRequest(c, Screen), cookie) + return GetFBConfigsCookie{cookie} +} + +// GetFBConfigsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetFBConfigsUnchecked(c *xgb.Conn, Screen uint32) GetFBConfigsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetFBConfigs' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getFBConfigsRequest(c, Screen), cookie) + return GetFBConfigsCookie{cookie} +} + +// GetFBConfigsReply represents the data returned from a GetFBConfigs request. +type GetFBConfigsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumFbConfigs uint32 + NumProperties uint32 + // padding: 16 bytes + PropertyList []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a GetFBConfigs request. +func (cook GetFBConfigsCookie) Reply() (*GetFBConfigsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getFBConfigsReply(buf), nil +} + +// getFBConfigsReply reads a byte slice into a GetFBConfigsReply value. +func getFBConfigsReply(buf []byte) *GetFBConfigsReply { + v := new(GetFBConfigsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumFbConfigs = xgb.Get32(buf[b:]) + b += 4 + + v.NumProperties = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + v.PropertyList = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.PropertyList[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetFBConfigs +// getFBConfigsRequest writes a GetFBConfigs request to a byte slice. +func getFBConfigsRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 21 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// GetFloatvCookie is a cookie used only for GetFloatv requests. +type GetFloatvCookie struct { + *xgb.Cookie +} + +// GetFloatv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetFloatvCookie.Reply() +func GetFloatv(c *xgb.Conn, ContextTag ContextTag, Pname uint32) GetFloatvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetFloatv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getFloatvRequest(c, ContextTag, Pname), cookie) + return GetFloatvCookie{cookie} +} + +// GetFloatvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetFloatvUnchecked(c *xgb.Conn, ContextTag ContextTag, Pname uint32) GetFloatvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetFloatv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getFloatvRequest(c, ContextTag, Pname), cookie) + return GetFloatvCookie{cookie} +} + +// GetFloatvReply represents the data returned from a GetFloatv request. +type GetFloatvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetFloatv request. +func (cook GetFloatvCookie) Reply() (*GetFloatvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getFloatvReply(buf), nil +} + +// getFloatvReply reads a byte slice into a GetFloatvReply value. +func getFloatvReply(buf []byte) *GetFloatvReply { + v := new(GetFloatvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetFloatv +// getFloatvRequest writes a GetFloatv request to a byte slice. +func getFloatvRequest(c *xgb.Conn, ContextTag ContextTag, Pname uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 116 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetHistogramCookie is a cookie used only for GetHistogram requests. +type GetHistogramCookie struct { + *xgb.Cookie +} + +// GetHistogram sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetHistogramCookie.Reply() +func GetHistogram(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool, Reset bool) GetHistogramCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetHistogram' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getHistogramRequest(c, ContextTag, Target, Format, Type, SwapBytes, Reset), cookie) + return GetHistogramCookie{cookie} +} + +// GetHistogramUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetHistogramUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool, Reset bool) GetHistogramCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetHistogram' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getHistogramRequest(c, ContextTag, Target, Format, Type, SwapBytes, Reset), cookie) + return GetHistogramCookie{cookie} +} + +// GetHistogramReply represents the data returned from a GetHistogram request. +type GetHistogramReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 8 bytes + Width int32 + // padding: 12 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetHistogram request. +func (cook GetHistogramCookie) Reply() (*GetHistogramReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getHistogramReply(buf), nil +} + +// getHistogramReply reads a byte slice into a GetHistogramReply value. +func getHistogramReply(buf []byte) *GetHistogramReply { + v := new(GetHistogramReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 8 // padding + + v.Width = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetHistogram +// getHistogramRequest writes a GetHistogram request to a byte slice. +func getHistogramRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool, Reset bool) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 154 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if Reset { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetHistogramParameterfvCookie is a cookie used only for GetHistogramParameterfv requests. +type GetHistogramParameterfvCookie struct { + *xgb.Cookie +} + +// GetHistogramParameterfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetHistogramParameterfvCookie.Reply() +func GetHistogramParameterfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetHistogramParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetHistogramParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getHistogramParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetHistogramParameterfvCookie{cookie} +} + +// GetHistogramParameterfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetHistogramParameterfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetHistogramParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetHistogramParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getHistogramParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetHistogramParameterfvCookie{cookie} +} + +// GetHistogramParameterfvReply represents the data returned from a GetHistogramParameterfv request. +type GetHistogramParameterfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetHistogramParameterfv request. +func (cook GetHistogramParameterfvCookie) Reply() (*GetHistogramParameterfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getHistogramParameterfvReply(buf), nil +} + +// getHistogramParameterfvReply reads a byte slice into a GetHistogramParameterfvReply value. +func getHistogramParameterfvReply(buf []byte) *GetHistogramParameterfvReply { + v := new(GetHistogramParameterfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetHistogramParameterfv +// getHistogramParameterfvRequest writes a GetHistogramParameterfv request to a byte slice. +func getHistogramParameterfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 155 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetHistogramParameterivCookie is a cookie used only for GetHistogramParameteriv requests. +type GetHistogramParameterivCookie struct { + *xgb.Cookie +} + +// GetHistogramParameteriv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetHistogramParameterivCookie.Reply() +func GetHistogramParameteriv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetHistogramParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetHistogramParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getHistogramParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetHistogramParameterivCookie{cookie} +} + +// GetHistogramParameterivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetHistogramParameterivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetHistogramParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetHistogramParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getHistogramParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetHistogramParameterivCookie{cookie} +} + +// GetHistogramParameterivReply represents the data returned from a GetHistogramParameteriv request. +type GetHistogramParameterivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetHistogramParameteriv request. +func (cook GetHistogramParameterivCookie) Reply() (*GetHistogramParameterivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getHistogramParameterivReply(buf), nil +} + +// getHistogramParameterivReply reads a byte slice into a GetHistogramParameterivReply value. +func getHistogramParameterivReply(buf []byte) *GetHistogramParameterivReply { + v := new(GetHistogramParameterivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetHistogramParameteriv +// getHistogramParameterivRequest writes a GetHistogramParameteriv request to a byte slice. +func getHistogramParameterivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 156 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetIntegervCookie is a cookie used only for GetIntegerv requests. +type GetIntegervCookie struct { + *xgb.Cookie +} + +// GetIntegerv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetIntegervCookie.Reply() +func GetIntegerv(c *xgb.Conn, ContextTag ContextTag, Pname uint32) GetIntegervCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetIntegerv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getIntegervRequest(c, ContextTag, Pname), cookie) + return GetIntegervCookie{cookie} +} + +// GetIntegervUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetIntegervUnchecked(c *xgb.Conn, ContextTag ContextTag, Pname uint32) GetIntegervCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetIntegerv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getIntegervRequest(c, ContextTag, Pname), cookie) + return GetIntegervCookie{cookie} +} + +// GetIntegervReply represents the data returned from a GetIntegerv request. +type GetIntegervReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetIntegerv request. +func (cook GetIntegervCookie) Reply() (*GetIntegervReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getIntegervReply(buf), nil +} + +// getIntegervReply reads a byte slice into a GetIntegervReply value. +func getIntegervReply(buf []byte) *GetIntegervReply { + v := new(GetIntegervReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetIntegerv +// getIntegervRequest writes a GetIntegerv request to a byte slice. +func getIntegervRequest(c *xgb.Conn, ContextTag ContextTag, Pname uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 117 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetLightfvCookie is a cookie used only for GetLightfv requests. +type GetLightfvCookie struct { + *xgb.Cookie +} + +// GetLightfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetLightfvCookie.Reply() +func GetLightfv(c *xgb.Conn, ContextTag ContextTag, Light uint32, Pname uint32) GetLightfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetLightfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getLightfvRequest(c, ContextTag, Light, Pname), cookie) + return GetLightfvCookie{cookie} +} + +// GetLightfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetLightfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Light uint32, Pname uint32) GetLightfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetLightfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getLightfvRequest(c, ContextTag, Light, Pname), cookie) + return GetLightfvCookie{cookie} +} + +// GetLightfvReply represents the data returned from a GetLightfv request. +type GetLightfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetLightfv request. +func (cook GetLightfvCookie) Reply() (*GetLightfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getLightfvReply(buf), nil +} + +// getLightfvReply reads a byte slice into a GetLightfvReply value. +func getLightfvReply(buf []byte) *GetLightfvReply { + v := new(GetLightfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetLightfv +// getLightfvRequest writes a GetLightfv request to a byte slice. +func getLightfvRequest(c *xgb.Conn, ContextTag ContextTag, Light uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 118 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Light) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetLightivCookie is a cookie used only for GetLightiv requests. +type GetLightivCookie struct { + *xgb.Cookie +} + +// GetLightiv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetLightivCookie.Reply() +func GetLightiv(c *xgb.Conn, ContextTag ContextTag, Light uint32, Pname uint32) GetLightivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetLightiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getLightivRequest(c, ContextTag, Light, Pname), cookie) + return GetLightivCookie{cookie} +} + +// GetLightivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetLightivUnchecked(c *xgb.Conn, ContextTag ContextTag, Light uint32, Pname uint32) GetLightivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetLightiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getLightivRequest(c, ContextTag, Light, Pname), cookie) + return GetLightivCookie{cookie} +} + +// GetLightivReply represents the data returned from a GetLightiv request. +type GetLightivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetLightiv request. +func (cook GetLightivCookie) Reply() (*GetLightivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getLightivReply(buf), nil +} + +// getLightivReply reads a byte slice into a GetLightivReply value. +func getLightivReply(buf []byte) *GetLightivReply { + v := new(GetLightivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetLightiv +// getLightivRequest writes a GetLightiv request to a byte slice. +func getLightivRequest(c *xgb.Conn, ContextTag ContextTag, Light uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 119 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Light) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetMapdvCookie is a cookie used only for GetMapdv requests. +type GetMapdvCookie struct { + *xgb.Cookie +} + +// GetMapdv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMapdvCookie.Reply() +func GetMapdv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) GetMapdvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMapdv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMapdvRequest(c, ContextTag, Target, Query), cookie) + return GetMapdvCookie{cookie} +} + +// GetMapdvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMapdvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) GetMapdvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMapdv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMapdvRequest(c, ContextTag, Target, Query), cookie) + return GetMapdvCookie{cookie} +} + +// GetMapdvReply represents the data returned from a GetMapdv request. +type GetMapdvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float64 + // padding: 8 bytes + Data []Float64 // size: xgb.Pad((int(N) * 8)) +} + +// Reply blocks and returns the reply data for a GetMapdv request. +func (cook GetMapdvCookie) Reply() (*GetMapdvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMapdvReply(buf), nil +} + +// getMapdvReply reads a byte slice into a GetMapdvReply value. +func getMapdvReply(buf []byte) *GetMapdvReply { + v := new(GetMapdvReply) + b := 1 // skip reply determinant + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 1 // padding + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float64(xgb.Get64(buf[b:])) + b += 8 + + b += 8 // padding + + v.Data = make([]Float64, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float64(xgb.Get64(buf[b:])) + b += 8 + } + + return v +} + +// Write request to wire for GetMapdv +// getMapdvRequest writes a GetMapdv request to a byte slice. +func getMapdvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 120 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Query) + b += 4 + + return buf +} + +// GetMapfvCookie is a cookie used only for GetMapfv requests. +type GetMapfvCookie struct { + *xgb.Cookie +} + +// GetMapfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMapfvCookie.Reply() +func GetMapfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) GetMapfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMapfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMapfvRequest(c, ContextTag, Target, Query), cookie) + return GetMapfvCookie{cookie} +} + +// GetMapfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMapfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) GetMapfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMapfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMapfvRequest(c, ContextTag, Target, Query), cookie) + return GetMapfvCookie{cookie} +} + +// GetMapfvReply represents the data returned from a GetMapfv request. +type GetMapfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetMapfv request. +func (cook GetMapfvCookie) Reply() (*GetMapfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMapfvReply(buf), nil +} + +// getMapfvReply reads a byte slice into a GetMapfvReply value. +func getMapfvReply(buf []byte) *GetMapfvReply { + v := new(GetMapfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetMapfv +// getMapfvRequest writes a GetMapfv request to a byte slice. +func getMapfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 121 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Query) + b += 4 + + return buf +} + +// GetMapivCookie is a cookie used only for GetMapiv requests. +type GetMapivCookie struct { + *xgb.Cookie +} + +// GetMapiv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMapivCookie.Reply() +func GetMapiv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) GetMapivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMapiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMapivRequest(c, ContextTag, Target, Query), cookie) + return GetMapivCookie{cookie} +} + +// GetMapivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMapivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) GetMapivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMapiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMapivRequest(c, ContextTag, Target, Query), cookie) + return GetMapivCookie{cookie} +} + +// GetMapivReply represents the data returned from a GetMapiv request. +type GetMapivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetMapiv request. +func (cook GetMapivCookie) Reply() (*GetMapivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMapivReply(buf), nil +} + +// getMapivReply reads a byte slice into a GetMapivReply value. +func getMapivReply(buf []byte) *GetMapivReply { + v := new(GetMapivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetMapiv +// getMapivRequest writes a GetMapiv request to a byte slice. +func getMapivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Query uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 122 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Query) + b += 4 + + return buf +} + +// GetMaterialfvCookie is a cookie used only for GetMaterialfv requests. +type GetMaterialfvCookie struct { + *xgb.Cookie +} + +// GetMaterialfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMaterialfvCookie.Reply() +func GetMaterialfv(c *xgb.Conn, ContextTag ContextTag, Face uint32, Pname uint32) GetMaterialfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMaterialfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMaterialfvRequest(c, ContextTag, Face, Pname), cookie) + return GetMaterialfvCookie{cookie} +} + +// GetMaterialfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMaterialfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Face uint32, Pname uint32) GetMaterialfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMaterialfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMaterialfvRequest(c, ContextTag, Face, Pname), cookie) + return GetMaterialfvCookie{cookie} +} + +// GetMaterialfvReply represents the data returned from a GetMaterialfv request. +type GetMaterialfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetMaterialfv request. +func (cook GetMaterialfvCookie) Reply() (*GetMaterialfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMaterialfvReply(buf), nil +} + +// getMaterialfvReply reads a byte slice into a GetMaterialfvReply value. +func getMaterialfvReply(buf []byte) *GetMaterialfvReply { + v := new(GetMaterialfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetMaterialfv +// getMaterialfvRequest writes a GetMaterialfv request to a byte slice. +func getMaterialfvRequest(c *xgb.Conn, ContextTag ContextTag, Face uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 123 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Face) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetMaterialivCookie is a cookie used only for GetMaterialiv requests. +type GetMaterialivCookie struct { + *xgb.Cookie +} + +// GetMaterialiv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMaterialivCookie.Reply() +func GetMaterialiv(c *xgb.Conn, ContextTag ContextTag, Face uint32, Pname uint32) GetMaterialivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMaterialiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMaterialivRequest(c, ContextTag, Face, Pname), cookie) + return GetMaterialivCookie{cookie} +} + +// GetMaterialivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMaterialivUnchecked(c *xgb.Conn, ContextTag ContextTag, Face uint32, Pname uint32) GetMaterialivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMaterialiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMaterialivRequest(c, ContextTag, Face, Pname), cookie) + return GetMaterialivCookie{cookie} +} + +// GetMaterialivReply represents the data returned from a GetMaterialiv request. +type GetMaterialivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetMaterialiv request. +func (cook GetMaterialivCookie) Reply() (*GetMaterialivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMaterialivReply(buf), nil +} + +// getMaterialivReply reads a byte slice into a GetMaterialivReply value. +func getMaterialivReply(buf []byte) *GetMaterialivReply { + v := new(GetMaterialivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetMaterialiv +// getMaterialivRequest writes a GetMaterialiv request to a byte slice. +func getMaterialivRequest(c *xgb.Conn, ContextTag ContextTag, Face uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 124 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Face) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetMinmaxCookie is a cookie used only for GetMinmax requests. +type GetMinmaxCookie struct { + *xgb.Cookie +} + +// GetMinmax sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMinmaxCookie.Reply() +func GetMinmax(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool, Reset bool) GetMinmaxCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMinmax' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMinmaxRequest(c, ContextTag, Target, Format, Type, SwapBytes, Reset), cookie) + return GetMinmaxCookie{cookie} +} + +// GetMinmaxUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMinmaxUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool, Reset bool) GetMinmaxCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMinmax' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMinmaxRequest(c, ContextTag, Target, Format, Type, SwapBytes, Reset), cookie) + return GetMinmaxCookie{cookie} +} + +// GetMinmaxReply represents the data returned from a GetMinmax request. +type GetMinmaxReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetMinmax request. +func (cook GetMinmaxCookie) Reply() (*GetMinmaxReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMinmaxReply(buf), nil +} + +// getMinmaxReply reads a byte slice into a GetMinmaxReply value. +func getMinmaxReply(buf []byte) *GetMinmaxReply { + v := new(GetMinmaxReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetMinmax +// getMinmaxRequest writes a GetMinmax request to a byte slice. +func getMinmaxRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool, Reset bool) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 157 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if Reset { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetMinmaxParameterfvCookie is a cookie used only for GetMinmaxParameterfv requests. +type GetMinmaxParameterfvCookie struct { + *xgb.Cookie +} + +// GetMinmaxParameterfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMinmaxParameterfvCookie.Reply() +func GetMinmaxParameterfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetMinmaxParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMinmaxParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMinmaxParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetMinmaxParameterfvCookie{cookie} +} + +// GetMinmaxParameterfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMinmaxParameterfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetMinmaxParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMinmaxParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMinmaxParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetMinmaxParameterfvCookie{cookie} +} + +// GetMinmaxParameterfvReply represents the data returned from a GetMinmaxParameterfv request. +type GetMinmaxParameterfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetMinmaxParameterfv request. +func (cook GetMinmaxParameterfvCookie) Reply() (*GetMinmaxParameterfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMinmaxParameterfvReply(buf), nil +} + +// getMinmaxParameterfvReply reads a byte slice into a GetMinmaxParameterfvReply value. +func getMinmaxParameterfvReply(buf []byte) *GetMinmaxParameterfvReply { + v := new(GetMinmaxParameterfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetMinmaxParameterfv +// getMinmaxParameterfvRequest writes a GetMinmaxParameterfv request to a byte slice. +func getMinmaxParameterfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 158 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetMinmaxParameterivCookie is a cookie used only for GetMinmaxParameteriv requests. +type GetMinmaxParameterivCookie struct { + *xgb.Cookie +} + +// GetMinmaxParameteriv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMinmaxParameterivCookie.Reply() +func GetMinmaxParameteriv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetMinmaxParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMinmaxParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMinmaxParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetMinmaxParameterivCookie{cookie} +} + +// GetMinmaxParameterivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMinmaxParameterivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetMinmaxParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetMinmaxParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMinmaxParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetMinmaxParameterivCookie{cookie} +} + +// GetMinmaxParameterivReply represents the data returned from a GetMinmaxParameteriv request. +type GetMinmaxParameterivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetMinmaxParameteriv request. +func (cook GetMinmaxParameterivCookie) Reply() (*GetMinmaxParameterivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMinmaxParameterivReply(buf), nil +} + +// getMinmaxParameterivReply reads a byte slice into a GetMinmaxParameterivReply value. +func getMinmaxParameterivReply(buf []byte) *GetMinmaxParameterivReply { + v := new(GetMinmaxParameterivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetMinmaxParameteriv +// getMinmaxParameterivRequest writes a GetMinmaxParameteriv request to a byte slice. +func getMinmaxParameterivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 159 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetPixelMapfvCookie is a cookie used only for GetPixelMapfv requests. +type GetPixelMapfvCookie struct { + *xgb.Cookie +} + +// GetPixelMapfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPixelMapfvCookie.Reply() +func GetPixelMapfv(c *xgb.Conn, ContextTag ContextTag, Map uint32) GetPixelMapfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPixelMapfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPixelMapfvRequest(c, ContextTag, Map), cookie) + return GetPixelMapfvCookie{cookie} +} + +// GetPixelMapfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPixelMapfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Map uint32) GetPixelMapfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPixelMapfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPixelMapfvRequest(c, ContextTag, Map), cookie) + return GetPixelMapfvCookie{cookie} +} + +// GetPixelMapfvReply represents the data returned from a GetPixelMapfv request. +type GetPixelMapfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetPixelMapfv request. +func (cook GetPixelMapfvCookie) Reply() (*GetPixelMapfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPixelMapfvReply(buf), nil +} + +// getPixelMapfvReply reads a byte slice into a GetPixelMapfvReply value. +func getPixelMapfvReply(buf []byte) *GetPixelMapfvReply { + v := new(GetPixelMapfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetPixelMapfv +// getPixelMapfvRequest writes a GetPixelMapfv request to a byte slice. +func getPixelMapfvRequest(c *xgb.Conn, ContextTag ContextTag, Map uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 125 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Map) + b += 4 + + return buf +} + +// GetPixelMapuivCookie is a cookie used only for GetPixelMapuiv requests. +type GetPixelMapuivCookie struct { + *xgb.Cookie +} + +// GetPixelMapuiv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPixelMapuivCookie.Reply() +func GetPixelMapuiv(c *xgb.Conn, ContextTag ContextTag, Map uint32) GetPixelMapuivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPixelMapuiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPixelMapuivRequest(c, ContextTag, Map), cookie) + return GetPixelMapuivCookie{cookie} +} + +// GetPixelMapuivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPixelMapuivUnchecked(c *xgb.Conn, ContextTag ContextTag, Map uint32) GetPixelMapuivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPixelMapuiv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPixelMapuivRequest(c, ContextTag, Map), cookie) + return GetPixelMapuivCookie{cookie} +} + +// GetPixelMapuivReply represents the data returned from a GetPixelMapuiv request. +type GetPixelMapuivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum uint32 + // padding: 12 bytes + Data []uint32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetPixelMapuiv request. +func (cook GetPixelMapuivCookie) Reply() (*GetPixelMapuivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPixelMapuivReply(buf), nil +} + +// getPixelMapuivReply reads a byte slice into a GetPixelMapuivReply value. +func getPixelMapuivReply(buf []byte) *GetPixelMapuivReply { + v := new(GetPixelMapuivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Data = make([]uint32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetPixelMapuiv +// getPixelMapuivRequest writes a GetPixelMapuiv request to a byte slice. +func getPixelMapuivRequest(c *xgb.Conn, ContextTag ContextTag, Map uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 126 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Map) + b += 4 + + return buf +} + +// GetPixelMapusvCookie is a cookie used only for GetPixelMapusv requests. +type GetPixelMapusvCookie struct { + *xgb.Cookie +} + +// GetPixelMapusv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPixelMapusvCookie.Reply() +func GetPixelMapusv(c *xgb.Conn, ContextTag ContextTag, Map uint32) GetPixelMapusvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPixelMapusv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPixelMapusvRequest(c, ContextTag, Map), cookie) + return GetPixelMapusvCookie{cookie} +} + +// GetPixelMapusvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPixelMapusvUnchecked(c *xgb.Conn, ContextTag ContextTag, Map uint32) GetPixelMapusvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPixelMapusv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPixelMapusvRequest(c, ContextTag, Map), cookie) + return GetPixelMapusvCookie{cookie} +} + +// GetPixelMapusvReply represents the data returned from a GetPixelMapusv request. +type GetPixelMapusvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum uint16 + // padding: 16 bytes + Data []uint16 // size: xgb.Pad((int(N) * 2)) +} + +// Reply blocks and returns the reply data for a GetPixelMapusv request. +func (cook GetPixelMapusvCookie) Reply() (*GetPixelMapusvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPixelMapusvReply(buf), nil +} + +// getPixelMapusvReply reads a byte slice into a GetPixelMapusvReply value. +func getPixelMapusvReply(buf []byte) *GetPixelMapusvReply { + v := new(GetPixelMapusvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = xgb.Get16(buf[b:]) + b += 2 + + b += 16 // padding + + v.Data = make([]uint16, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = xgb.Get16(buf[b:]) + b += 2 + } + + return v +} + +// Write request to wire for GetPixelMapusv +// getPixelMapusvRequest writes a GetPixelMapusv request to a byte slice. +func getPixelMapusvRequest(c *xgb.Conn, ContextTag ContextTag, Map uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 127 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Map) + b += 4 + + return buf +} + +// GetPolygonStippleCookie is a cookie used only for GetPolygonStipple requests. +type GetPolygonStippleCookie struct { + *xgb.Cookie +} + +// GetPolygonStipple sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPolygonStippleCookie.Reply() +func GetPolygonStipple(c *xgb.Conn, ContextTag ContextTag, LsbFirst bool) GetPolygonStippleCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPolygonStipple' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPolygonStippleRequest(c, ContextTag, LsbFirst), cookie) + return GetPolygonStippleCookie{cookie} +} + +// GetPolygonStippleUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPolygonStippleUnchecked(c *xgb.Conn, ContextTag ContextTag, LsbFirst bool) GetPolygonStippleCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetPolygonStipple' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPolygonStippleRequest(c, ContextTag, LsbFirst), cookie) + return GetPolygonStippleCookie{cookie} +} + +// GetPolygonStippleReply represents the data returned from a GetPolygonStipple request. +type GetPolygonStippleReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetPolygonStipple request. +func (cook GetPolygonStippleCookie) Reply() (*GetPolygonStippleReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPolygonStippleReply(buf), nil +} + +// getPolygonStippleReply reads a byte slice into a GetPolygonStippleReply value. +func getPolygonStippleReply(buf []byte) *GetPolygonStippleReply { + v := new(GetPolygonStippleReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetPolygonStipple +// getPolygonStippleRequest writes a GetPolygonStipple request to a byte slice. +func getPolygonStippleRequest(c *xgb.Conn, ContextTag ContextTag, LsbFirst bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 128 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + if LsbFirst { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetQueryObjectivARBCookie is a cookie used only for GetQueryObjectivARB requests. +type GetQueryObjectivARBCookie struct { + *xgb.Cookie +} + +// GetQueryObjectivARB sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetQueryObjectivARBCookie.Reply() +func GetQueryObjectivARB(c *xgb.Conn, ContextTag ContextTag, Id uint32, Pname uint32) GetQueryObjectivARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetQueryObjectivARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getQueryObjectivARBRequest(c, ContextTag, Id, Pname), cookie) + return GetQueryObjectivARBCookie{cookie} +} + +// GetQueryObjectivARBUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetQueryObjectivARBUnchecked(c *xgb.Conn, ContextTag ContextTag, Id uint32, Pname uint32) GetQueryObjectivARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetQueryObjectivARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getQueryObjectivARBRequest(c, ContextTag, Id, Pname), cookie) + return GetQueryObjectivARBCookie{cookie} +} + +// GetQueryObjectivARBReply represents the data returned from a GetQueryObjectivARB request. +type GetQueryObjectivARBReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetQueryObjectivARB request. +func (cook GetQueryObjectivARBCookie) Reply() (*GetQueryObjectivARBReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getQueryObjectivARBReply(buf), nil +} + +// getQueryObjectivARBReply reads a byte slice into a GetQueryObjectivARBReply value. +func getQueryObjectivARBReply(buf []byte) *GetQueryObjectivARBReply { + v := new(GetQueryObjectivARBReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetQueryObjectivARB +// getQueryObjectivARBRequest writes a GetQueryObjectivARB request to a byte slice. +func getQueryObjectivARBRequest(c *xgb.Conn, ContextTag ContextTag, Id uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 165 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Id) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetQueryObjectuivARBCookie is a cookie used only for GetQueryObjectuivARB requests. +type GetQueryObjectuivARBCookie struct { + *xgb.Cookie +} + +// GetQueryObjectuivARB sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetQueryObjectuivARBCookie.Reply() +func GetQueryObjectuivARB(c *xgb.Conn, ContextTag ContextTag, Id uint32, Pname uint32) GetQueryObjectuivARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetQueryObjectuivARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getQueryObjectuivARBRequest(c, ContextTag, Id, Pname), cookie) + return GetQueryObjectuivARBCookie{cookie} +} + +// GetQueryObjectuivARBUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetQueryObjectuivARBUnchecked(c *xgb.Conn, ContextTag ContextTag, Id uint32, Pname uint32) GetQueryObjectuivARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetQueryObjectuivARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getQueryObjectuivARBRequest(c, ContextTag, Id, Pname), cookie) + return GetQueryObjectuivARBCookie{cookie} +} + +// GetQueryObjectuivARBReply represents the data returned from a GetQueryObjectuivARB request. +type GetQueryObjectuivARBReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum uint32 + // padding: 12 bytes + Data []uint32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetQueryObjectuivARB request. +func (cook GetQueryObjectuivARBCookie) Reply() (*GetQueryObjectuivARBReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getQueryObjectuivARBReply(buf), nil +} + +// getQueryObjectuivARBReply reads a byte slice into a GetQueryObjectuivARBReply value. +func getQueryObjectuivARBReply(buf []byte) *GetQueryObjectuivARBReply { + v := new(GetQueryObjectuivARBReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Data = make([]uint32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetQueryObjectuivARB +// getQueryObjectuivARBRequest writes a GetQueryObjectuivARB request to a byte slice. +func getQueryObjectuivARBRequest(c *xgb.Conn, ContextTag ContextTag, Id uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 166 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Id) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetQueryivARBCookie is a cookie used only for GetQueryivARB requests. +type GetQueryivARBCookie struct { + *xgb.Cookie +} + +// GetQueryivARB sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetQueryivARBCookie.Reply() +func GetQueryivARB(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetQueryivARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetQueryivARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getQueryivARBRequest(c, ContextTag, Target, Pname), cookie) + return GetQueryivARBCookie{cookie} +} + +// GetQueryivARBUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetQueryivARBUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetQueryivARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetQueryivARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getQueryivARBRequest(c, ContextTag, Target, Pname), cookie) + return GetQueryivARBCookie{cookie} +} + +// GetQueryivARBReply represents the data returned from a GetQueryivARB request. +type GetQueryivARBReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetQueryivARB request. +func (cook GetQueryivARBCookie) Reply() (*GetQueryivARBReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getQueryivARBReply(buf), nil +} + +// getQueryivARBReply reads a byte slice into a GetQueryivARBReply value. +func getQueryivARBReply(buf []byte) *GetQueryivARBReply { + v := new(GetQueryivARBReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetQueryivARB +// getQueryivARBRequest writes a GetQueryivARB request to a byte slice. +func getQueryivARBRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 164 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetSeparableFilterCookie is a cookie used only for GetSeparableFilter requests. +type GetSeparableFilterCookie struct { + *xgb.Cookie +} + +// GetSeparableFilter sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetSeparableFilterCookie.Reply() +func GetSeparableFilter(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) GetSeparableFilterCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetSeparableFilter' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getSeparableFilterRequest(c, ContextTag, Target, Format, Type, SwapBytes), cookie) + return GetSeparableFilterCookie{cookie} +} + +// GetSeparableFilterUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetSeparableFilterUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) GetSeparableFilterCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetSeparableFilter' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getSeparableFilterRequest(c, ContextTag, Target, Format, Type, SwapBytes), cookie) + return GetSeparableFilterCookie{cookie} +} + +// GetSeparableFilterReply represents the data returned from a GetSeparableFilter request. +type GetSeparableFilterReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 8 bytes + RowW int32 + ColH int32 + // padding: 8 bytes + RowsAndCols []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetSeparableFilter request. +func (cook GetSeparableFilterCookie) Reply() (*GetSeparableFilterReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getSeparableFilterReply(buf), nil +} + +// getSeparableFilterReply reads a byte slice into a GetSeparableFilterReply value. +func getSeparableFilterReply(buf []byte) *GetSeparableFilterReply { + v := new(GetSeparableFilterReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 8 // padding + + v.RowW = int32(xgb.Get32(buf[b:])) + b += 4 + + v.ColH = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 8 // padding + + v.RowsAndCols = make([]byte, (int(v.Length) * 4)) + copy(v.RowsAndCols[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetSeparableFilter +// getSeparableFilterRequest writes a GetSeparableFilter request to a byte slice. +func getSeparableFilterRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Format uint32, Type uint32, SwapBytes bool) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 153 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetStringCookie is a cookie used only for GetString requests. +type GetStringCookie struct { + *xgb.Cookie +} + +// GetString sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetStringCookie.Reply() +func GetString(c *xgb.Conn, ContextTag ContextTag, Name uint32) GetStringCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetString' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getStringRequest(c, ContextTag, Name), cookie) + return GetStringCookie{cookie} +} + +// GetStringUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetStringUnchecked(c *xgb.Conn, ContextTag ContextTag, Name uint32) GetStringCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetString' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getStringRequest(c, ContextTag, Name), cookie) + return GetStringCookie{cookie} +} + +// GetStringReply represents the data returned from a GetString request. +type GetStringReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + // padding: 16 bytes + String string // size: xgb.Pad((int(N) * 1)) +} + +// Reply blocks and returns the reply data for a GetString request. +func (cook GetStringCookie) Reply() (*GetStringReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getStringReply(buf), nil +} + +// getStringReply reads a byte slice into a GetStringReply value. +func getStringReply(buf []byte) *GetStringReply { + v := new(GetStringReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + { + byteString := make([]byte, v.N) + copy(byteString[:v.N], buf[b:]) + v.String = string(byteString) + b += int(v.N) + } + + return v +} + +// Write request to wire for GetString +// getStringRequest writes a GetString request to a byte slice. +func getStringRequest(c *xgb.Conn, ContextTag ContextTag, Name uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 129 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Name) + b += 4 + + return buf +} + +// GetTexEnvfvCookie is a cookie used only for GetTexEnvfv requests. +type GetTexEnvfvCookie struct { + *xgb.Cookie +} + +// GetTexEnvfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexEnvfvCookie.Reply() +func GetTexEnvfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexEnvfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexEnvfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexEnvfvRequest(c, ContextTag, Target, Pname), cookie) + return GetTexEnvfvCookie{cookie} +} + +// GetTexEnvfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexEnvfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexEnvfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexEnvfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexEnvfvRequest(c, ContextTag, Target, Pname), cookie) + return GetTexEnvfvCookie{cookie} +} + +// GetTexEnvfvReply represents the data returned from a GetTexEnvfv request. +type GetTexEnvfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexEnvfv request. +func (cook GetTexEnvfvCookie) Reply() (*GetTexEnvfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexEnvfvReply(buf), nil +} + +// getTexEnvfvReply reads a byte slice into a GetTexEnvfvReply value. +func getTexEnvfvReply(buf []byte) *GetTexEnvfvReply { + v := new(GetTexEnvfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexEnvfv +// getTexEnvfvRequest writes a GetTexEnvfv request to a byte slice. +func getTexEnvfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 130 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexEnvivCookie is a cookie used only for GetTexEnviv requests. +type GetTexEnvivCookie struct { + *xgb.Cookie +} + +// GetTexEnviv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexEnvivCookie.Reply() +func GetTexEnviv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexEnvivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexEnviv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexEnvivRequest(c, ContextTag, Target, Pname), cookie) + return GetTexEnvivCookie{cookie} +} + +// GetTexEnvivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexEnvivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexEnvivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexEnviv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexEnvivRequest(c, ContextTag, Target, Pname), cookie) + return GetTexEnvivCookie{cookie} +} + +// GetTexEnvivReply represents the data returned from a GetTexEnviv request. +type GetTexEnvivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexEnviv request. +func (cook GetTexEnvivCookie) Reply() (*GetTexEnvivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexEnvivReply(buf), nil +} + +// getTexEnvivReply reads a byte slice into a GetTexEnvivReply value. +func getTexEnvivReply(buf []byte) *GetTexEnvivReply { + v := new(GetTexEnvivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexEnviv +// getTexEnvivRequest writes a GetTexEnviv request to a byte slice. +func getTexEnvivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 131 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexGendvCookie is a cookie used only for GetTexGendv requests. +type GetTexGendvCookie struct { + *xgb.Cookie +} + +// GetTexGendv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexGendvCookie.Reply() +func GetTexGendv(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) GetTexGendvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexGendv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexGendvRequest(c, ContextTag, Coord, Pname), cookie) + return GetTexGendvCookie{cookie} +} + +// GetTexGendvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexGendvUnchecked(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) GetTexGendvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexGendv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexGendvRequest(c, ContextTag, Coord, Pname), cookie) + return GetTexGendvCookie{cookie} +} + +// GetTexGendvReply represents the data returned from a GetTexGendv request. +type GetTexGendvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float64 + // padding: 8 bytes + Data []Float64 // size: xgb.Pad((int(N) * 8)) +} + +// Reply blocks and returns the reply data for a GetTexGendv request. +func (cook GetTexGendvCookie) Reply() (*GetTexGendvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexGendvReply(buf), nil +} + +// getTexGendvReply reads a byte slice into a GetTexGendvReply value. +func getTexGendvReply(buf []byte) *GetTexGendvReply { + v := new(GetTexGendvReply) + b := 1 // skip reply determinant + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 1 // padding + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float64(xgb.Get64(buf[b:])) + b += 8 + + b += 8 // padding + + v.Data = make([]Float64, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float64(xgb.Get64(buf[b:])) + b += 8 + } + + return v +} + +// Write request to wire for GetTexGendv +// getTexGendvRequest writes a GetTexGendv request to a byte slice. +func getTexGendvRequest(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 132 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Coord) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexGenfvCookie is a cookie used only for GetTexGenfv requests. +type GetTexGenfvCookie struct { + *xgb.Cookie +} + +// GetTexGenfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexGenfvCookie.Reply() +func GetTexGenfv(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) GetTexGenfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexGenfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexGenfvRequest(c, ContextTag, Coord, Pname), cookie) + return GetTexGenfvCookie{cookie} +} + +// GetTexGenfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexGenfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) GetTexGenfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexGenfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexGenfvRequest(c, ContextTag, Coord, Pname), cookie) + return GetTexGenfvCookie{cookie} +} + +// GetTexGenfvReply represents the data returned from a GetTexGenfv request. +type GetTexGenfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexGenfv request. +func (cook GetTexGenfvCookie) Reply() (*GetTexGenfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexGenfvReply(buf), nil +} + +// getTexGenfvReply reads a byte slice into a GetTexGenfvReply value. +func getTexGenfvReply(buf []byte) *GetTexGenfvReply { + v := new(GetTexGenfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexGenfv +// getTexGenfvRequest writes a GetTexGenfv request to a byte slice. +func getTexGenfvRequest(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 133 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Coord) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexGenivCookie is a cookie used only for GetTexGeniv requests. +type GetTexGenivCookie struct { + *xgb.Cookie +} + +// GetTexGeniv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexGenivCookie.Reply() +func GetTexGeniv(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) GetTexGenivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexGeniv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexGenivRequest(c, ContextTag, Coord, Pname), cookie) + return GetTexGenivCookie{cookie} +} + +// GetTexGenivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexGenivUnchecked(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) GetTexGenivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexGeniv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexGenivRequest(c, ContextTag, Coord, Pname), cookie) + return GetTexGenivCookie{cookie} +} + +// GetTexGenivReply represents the data returned from a GetTexGeniv request. +type GetTexGenivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexGeniv request. +func (cook GetTexGenivCookie) Reply() (*GetTexGenivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexGenivReply(buf), nil +} + +// getTexGenivReply reads a byte slice into a GetTexGenivReply value. +func getTexGenivReply(buf []byte) *GetTexGenivReply { + v := new(GetTexGenivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexGeniv +// getTexGenivRequest writes a GetTexGeniv request to a byte slice. +func getTexGenivRequest(c *xgb.Conn, ContextTag ContextTag, Coord uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 134 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Coord) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexImageCookie is a cookie used only for GetTexImage requests. +type GetTexImageCookie struct { + *xgb.Cookie +} + +// GetTexImage sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexImageCookie.Reply() +func GetTexImage(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Format uint32, Type uint32, SwapBytes bool) GetTexImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexImage' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexImageRequest(c, ContextTag, Target, Level, Format, Type, SwapBytes), cookie) + return GetTexImageCookie{cookie} +} + +// GetTexImageUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexImageUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Format uint32, Type uint32, SwapBytes bool) GetTexImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexImage' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexImageRequest(c, ContextTag, Target, Level, Format, Type, SwapBytes), cookie) + return GetTexImageCookie{cookie} +} + +// GetTexImageReply represents the data returned from a GetTexImage request. +type GetTexImageReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 8 bytes + Width int32 + Height int32 + Depth int32 + // padding: 4 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetTexImage request. +func (cook GetTexImageCookie) Reply() (*GetTexImageReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexImageReply(buf), nil +} + +// getTexImageReply reads a byte slice into a GetTexImageReply value. +func getTexImageReply(buf []byte) *GetTexImageReply { + v := new(GetTexImageReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 8 // padding + + v.Width = int32(xgb.Get32(buf[b:])) + b += 4 + + v.Height = int32(xgb.Get32(buf[b:])) + b += 4 + + v.Depth = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 4 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetTexImage +// getTexImageRequest writes a GetTexImage request to a byte slice. +func getTexImageRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Format uint32, Type uint32, SwapBytes bool) []byte { + size := 28 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 135 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], uint32(Level)) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetTexLevelParameterfvCookie is a cookie used only for GetTexLevelParameterfv requests. +type GetTexLevelParameterfvCookie struct { + *xgb.Cookie +} + +// GetTexLevelParameterfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexLevelParameterfvCookie.Reply() +func GetTexLevelParameterfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Pname uint32) GetTexLevelParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexLevelParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexLevelParameterfvRequest(c, ContextTag, Target, Level, Pname), cookie) + return GetTexLevelParameterfvCookie{cookie} +} + +// GetTexLevelParameterfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexLevelParameterfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Pname uint32) GetTexLevelParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexLevelParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexLevelParameterfvRequest(c, ContextTag, Target, Level, Pname), cookie) + return GetTexLevelParameterfvCookie{cookie} +} + +// GetTexLevelParameterfvReply represents the data returned from a GetTexLevelParameterfv request. +type GetTexLevelParameterfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexLevelParameterfv request. +func (cook GetTexLevelParameterfvCookie) Reply() (*GetTexLevelParameterfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexLevelParameterfvReply(buf), nil +} + +// getTexLevelParameterfvReply reads a byte slice into a GetTexLevelParameterfvReply value. +func getTexLevelParameterfvReply(buf []byte) *GetTexLevelParameterfvReply { + v := new(GetTexLevelParameterfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexLevelParameterfv +// getTexLevelParameterfvRequest writes a GetTexLevelParameterfv request to a byte slice. +func getTexLevelParameterfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Pname uint32) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 138 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], uint32(Level)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexLevelParameterivCookie is a cookie used only for GetTexLevelParameteriv requests. +type GetTexLevelParameterivCookie struct { + *xgb.Cookie +} + +// GetTexLevelParameteriv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexLevelParameterivCookie.Reply() +func GetTexLevelParameteriv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Pname uint32) GetTexLevelParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexLevelParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexLevelParameterivRequest(c, ContextTag, Target, Level, Pname), cookie) + return GetTexLevelParameterivCookie{cookie} +} + +// GetTexLevelParameterivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexLevelParameterivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Pname uint32) GetTexLevelParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexLevelParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexLevelParameterivRequest(c, ContextTag, Target, Level, Pname), cookie) + return GetTexLevelParameterivCookie{cookie} +} + +// GetTexLevelParameterivReply represents the data returned from a GetTexLevelParameteriv request. +type GetTexLevelParameterivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexLevelParameteriv request. +func (cook GetTexLevelParameterivCookie) Reply() (*GetTexLevelParameterivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexLevelParameterivReply(buf), nil +} + +// getTexLevelParameterivReply reads a byte slice into a GetTexLevelParameterivReply value. +func getTexLevelParameterivReply(buf []byte) *GetTexLevelParameterivReply { + v := new(GetTexLevelParameterivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexLevelParameteriv +// getTexLevelParameterivRequest writes a GetTexLevelParameteriv request to a byte slice. +func getTexLevelParameterivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Level int32, Pname uint32) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 139 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], uint32(Level)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexParameterfvCookie is a cookie used only for GetTexParameterfv requests. +type GetTexParameterfvCookie struct { + *xgb.Cookie +} + +// GetTexParameterfv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexParameterfvCookie.Reply() +func GetTexParameterfv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetTexParameterfvCookie{cookie} +} + +// GetTexParameterfvUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexParameterfvUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexParameterfvCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexParameterfv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexParameterfvRequest(c, ContextTag, Target, Pname), cookie) + return GetTexParameterfvCookie{cookie} +} + +// GetTexParameterfvReply represents the data returned from a GetTexParameterfv request. +type GetTexParameterfvReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum Float32 + // padding: 12 bytes + Data []Float32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexParameterfv request. +func (cook GetTexParameterfvCookie) Reply() (*GetTexParameterfvReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexParameterfvReply(buf), nil +} + +// getTexParameterfvReply reads a byte slice into a GetTexParameterfvReply value. +func getTexParameterfvReply(buf []byte) *GetTexParameterfvReply { + v := new(GetTexParameterfvReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = Float32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]Float32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = Float32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexParameterfv +// getTexParameterfvRequest writes a GetTexParameterfv request to a byte slice. +func getTexParameterfvRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 136 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetTexParameterivCookie is a cookie used only for GetTexParameteriv requests. +type GetTexParameterivCookie struct { + *xgb.Cookie +} + +// GetTexParameteriv sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetTexParameterivCookie.Reply() +func GetTexParameteriv(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getTexParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetTexParameterivCookie{cookie} +} + +// GetTexParameterivUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetTexParameterivUnchecked(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) GetTexParameterivCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetTexParameteriv' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getTexParameterivRequest(c, ContextTag, Target, Pname), cookie) + return GetTexParameterivCookie{cookie} +} + +// GetTexParameterivReply represents the data returned from a GetTexParameteriv request. +type GetTexParameterivReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + Datum int32 + // padding: 12 bytes + Data []int32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a GetTexParameteriv request. +func (cook GetTexParameterivCookie) Reply() (*GetTexParameterivReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getTexParameterivReply(buf), nil +} + +// getTexParameterivReply reads a byte slice into a GetTexParameterivReply value. +func getTexParameterivReply(buf []byte) *GetTexParameterivReply { + v := new(GetTexParameterivReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.Datum = int32(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + v.Data = make([]int32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetTexParameteriv +// getTexParameterivRequest writes a GetTexParameteriv request to a byte slice. +func getTexParameterivRequest(c *xgb.Conn, ContextTag ContextTag, Target uint32, Pname uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 137 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Target) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + return buf +} + +// GetVisualConfigsCookie is a cookie used only for GetVisualConfigs requests. +type GetVisualConfigsCookie struct { + *xgb.Cookie +} + +// GetVisualConfigs sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetVisualConfigsCookie.Reply() +func GetVisualConfigs(c *xgb.Conn, Screen uint32) GetVisualConfigsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetVisualConfigs' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getVisualConfigsRequest(c, Screen), cookie) + return GetVisualConfigsCookie{cookie} +} + +// GetVisualConfigsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetVisualConfigsUnchecked(c *xgb.Conn, Screen uint32) GetVisualConfigsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'GetVisualConfigs' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getVisualConfigsRequest(c, Screen), cookie) + return GetVisualConfigsCookie{cookie} +} + +// GetVisualConfigsReply represents the data returned from a GetVisualConfigs request. +type GetVisualConfigsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumVisuals uint32 + NumProperties uint32 + // padding: 16 bytes + PropertyList []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a GetVisualConfigs request. +func (cook GetVisualConfigsCookie) Reply() (*GetVisualConfigsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getVisualConfigsReply(buf), nil +} + +// getVisualConfigsReply reads a byte slice into a GetVisualConfigsReply value. +func getVisualConfigsReply(buf []byte) *GetVisualConfigsReply { + v := new(GetVisualConfigsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumVisuals = xgb.Get32(buf[b:]) + b += 4 + + v.NumProperties = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + v.PropertyList = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.PropertyList[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetVisualConfigs +// getVisualConfigsRequest writes a GetVisualConfigs request to a byte slice. +func getVisualConfigsRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// IsDirectCookie is a cookie used only for IsDirect requests. +type IsDirectCookie struct { + *xgb.Cookie +} + +// IsDirect sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsDirectCookie.Reply() +func IsDirect(c *xgb.Conn, Context Context) IsDirectCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsDirect' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isDirectRequest(c, Context), cookie) + return IsDirectCookie{cookie} +} + +// IsDirectUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsDirectUnchecked(c *xgb.Conn, Context Context) IsDirectCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsDirect' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isDirectRequest(c, Context), cookie) + return IsDirectCookie{cookie} +} + +// IsDirectReply represents the data returned from a IsDirect request. +type IsDirectReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + IsDirect bool + // padding: 23 bytes +} + +// Reply blocks and returns the reply data for a IsDirect request. +func (cook IsDirectCookie) Reply() (*IsDirectReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isDirectReply(buf), nil +} + +// isDirectReply reads a byte slice into a IsDirectReply value. +func isDirectReply(buf []byte) *IsDirectReply { + v := new(IsDirectReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.IsDirect = true + } else { + v.IsDirect = false + } + b += 1 + + b += 23 // padding + + return v +} + +// Write request to wire for IsDirect +// isDirectRequest writes a IsDirect request to a byte slice. +func isDirectRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// IsEnabledCookie is a cookie used only for IsEnabled requests. +type IsEnabledCookie struct { + *xgb.Cookie +} + +// IsEnabled sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsEnabledCookie.Reply() +func IsEnabled(c *xgb.Conn, ContextTag ContextTag, Capability uint32) IsEnabledCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsEnabled' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isEnabledRequest(c, ContextTag, Capability), cookie) + return IsEnabledCookie{cookie} +} + +// IsEnabledUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsEnabledUnchecked(c *xgb.Conn, ContextTag ContextTag, Capability uint32) IsEnabledCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsEnabled' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isEnabledRequest(c, ContextTag, Capability), cookie) + return IsEnabledCookie{cookie} +} + +// IsEnabledReply represents the data returned from a IsEnabled request. +type IsEnabledReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal Bool32 +} + +// Reply blocks and returns the reply data for a IsEnabled request. +func (cook IsEnabledCookie) Reply() (*IsEnabledReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isEnabledReply(buf), nil +} + +// isEnabledReply reads a byte slice into a IsEnabledReply value. +func isEnabledReply(buf []byte) *IsEnabledReply { + v := new(IsEnabledReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = Bool32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for IsEnabled +// isEnabledRequest writes a IsEnabled request to a byte slice. +func isEnabledRequest(c *xgb.Conn, ContextTag ContextTag, Capability uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 140 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Capability) + b += 4 + + return buf +} + +// IsListCookie is a cookie used only for IsList requests. +type IsListCookie struct { + *xgb.Cookie +} + +// IsList sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsListCookie.Reply() +func IsList(c *xgb.Conn, ContextTag ContextTag, List uint32) IsListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsList' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isListRequest(c, ContextTag, List), cookie) + return IsListCookie{cookie} +} + +// IsListUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsListUnchecked(c *xgb.Conn, ContextTag ContextTag, List uint32) IsListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsList' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isListRequest(c, ContextTag, List), cookie) + return IsListCookie{cookie} +} + +// IsListReply represents the data returned from a IsList request. +type IsListReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal Bool32 +} + +// Reply blocks and returns the reply data for a IsList request. +func (cook IsListCookie) Reply() (*IsListReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isListReply(buf), nil +} + +// isListReply reads a byte slice into a IsListReply value. +func isListReply(buf []byte) *IsListReply { + v := new(IsListReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = Bool32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for IsList +// isListRequest writes a IsList request to a byte slice. +func isListRequest(c *xgb.Conn, ContextTag ContextTag, List uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 141 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], List) + b += 4 + + return buf +} + +// IsQueryARBCookie is a cookie used only for IsQueryARB requests. +type IsQueryARBCookie struct { + *xgb.Cookie +} + +// IsQueryARB sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsQueryARBCookie.Reply() +func IsQueryARB(c *xgb.Conn, ContextTag ContextTag, Id uint32) IsQueryARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsQueryARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isQueryARBRequest(c, ContextTag, Id), cookie) + return IsQueryARBCookie{cookie} +} + +// IsQueryARBUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsQueryARBUnchecked(c *xgb.Conn, ContextTag ContextTag, Id uint32) IsQueryARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsQueryARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isQueryARBRequest(c, ContextTag, Id), cookie) + return IsQueryARBCookie{cookie} +} + +// IsQueryARBReply represents the data returned from a IsQueryARB request. +type IsQueryARBReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal Bool32 +} + +// Reply blocks and returns the reply data for a IsQueryARB request. +func (cook IsQueryARBCookie) Reply() (*IsQueryARBReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isQueryARBReply(buf), nil +} + +// isQueryARBReply reads a byte slice into a IsQueryARBReply value. +func isQueryARBReply(buf []byte) *IsQueryARBReply { + v := new(IsQueryARBReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = Bool32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for IsQueryARB +// isQueryARBRequest writes a IsQueryARB request to a byte slice. +func isQueryARBRequest(c *xgb.Conn, ContextTag ContextTag, Id uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 163 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Id) + b += 4 + + return buf +} + +// IsTextureCookie is a cookie used only for IsTexture requests. +type IsTextureCookie struct { + *xgb.Cookie +} + +// IsTexture sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsTextureCookie.Reply() +func IsTexture(c *xgb.Conn, ContextTag ContextTag, Texture uint32) IsTextureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsTexture' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isTextureRequest(c, ContextTag, Texture), cookie) + return IsTextureCookie{cookie} +} + +// IsTextureUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsTextureUnchecked(c *xgb.Conn, ContextTag ContextTag, Texture uint32) IsTextureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsTexture' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isTextureRequest(c, ContextTag, Texture), cookie) + return IsTextureCookie{cookie} +} + +// IsTextureReply represents the data returned from a IsTexture request. +type IsTextureReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal Bool32 +} + +// Reply blocks and returns the reply data for a IsTexture request. +func (cook IsTextureCookie) Reply() (*IsTextureReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isTextureReply(buf), nil +} + +// isTextureReply reads a byte slice into a IsTextureReply value. +func isTextureReply(buf []byte) *IsTextureReply { + v := new(IsTextureReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = Bool32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for IsTexture +// isTextureRequest writes a IsTexture request to a byte slice. +func isTextureRequest(c *xgb.Conn, ContextTag ContextTag, Texture uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 146 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Texture) + b += 4 + + return buf +} + +// MakeContextCurrentCookie is a cookie used only for MakeContextCurrent requests. +type MakeContextCurrentCookie struct { + *xgb.Cookie +} + +// MakeContextCurrent sends a checked request. +// If an error occurs, it will be returned with the reply by calling MakeContextCurrentCookie.Reply() +func MakeContextCurrent(c *xgb.Conn, OldContextTag ContextTag, Drawable Drawable, ReadDrawable Drawable, Context Context) MakeContextCurrentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'MakeContextCurrent' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(makeContextCurrentRequest(c, OldContextTag, Drawable, ReadDrawable, Context), cookie) + return MakeContextCurrentCookie{cookie} +} + +// MakeContextCurrentUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func MakeContextCurrentUnchecked(c *xgb.Conn, OldContextTag ContextTag, Drawable Drawable, ReadDrawable Drawable, Context Context) MakeContextCurrentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'MakeContextCurrent' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(makeContextCurrentRequest(c, OldContextTag, Drawable, ReadDrawable, Context), cookie) + return MakeContextCurrentCookie{cookie} +} + +// MakeContextCurrentReply represents the data returned from a MakeContextCurrent request. +type MakeContextCurrentReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextTag ContextTag + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a MakeContextCurrent request. +func (cook MakeContextCurrentCookie) Reply() (*MakeContextCurrentReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return makeContextCurrentReply(buf), nil +} + +// makeContextCurrentReply reads a byte slice into a MakeContextCurrentReply value. +func makeContextCurrentReply(buf []byte) *MakeContextCurrentReply { + v := new(MakeContextCurrentReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextTag = ContextTag(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for MakeContextCurrent +// makeContextCurrentRequest writes a MakeContextCurrent request to a byte slice. +func makeContextCurrentRequest(c *xgb.Conn, OldContextTag ContextTag, Drawable Drawable, ReadDrawable Drawable, Context Context) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 26 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(OldContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(ReadDrawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// MakeCurrentCookie is a cookie used only for MakeCurrent requests. +type MakeCurrentCookie struct { + *xgb.Cookie +} + +// MakeCurrent sends a checked request. +// If an error occurs, it will be returned with the reply by calling MakeCurrentCookie.Reply() +func MakeCurrent(c *xgb.Conn, Drawable Drawable, Context Context, OldContextTag ContextTag) MakeCurrentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'MakeCurrent' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(makeCurrentRequest(c, Drawable, Context, OldContextTag), cookie) + return MakeCurrentCookie{cookie} +} + +// MakeCurrentUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func MakeCurrentUnchecked(c *xgb.Conn, Drawable Drawable, Context Context, OldContextTag ContextTag) MakeCurrentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'MakeCurrent' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(makeCurrentRequest(c, Drawable, Context, OldContextTag), cookie) + return MakeCurrentCookie{cookie} +} + +// MakeCurrentReply represents the data returned from a MakeCurrent request. +type MakeCurrentReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextTag ContextTag + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a MakeCurrent request. +func (cook MakeCurrentCookie) Reply() (*MakeCurrentReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return makeCurrentReply(buf), nil +} + +// makeCurrentReply reads a byte slice into a MakeCurrentReply value. +func makeCurrentReply(buf []byte) *MakeCurrentReply { + v := new(MakeCurrentReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextTag = ContextTag(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for MakeCurrent +// makeCurrentRequest writes a MakeCurrent request to a byte slice. +func makeCurrentRequest(c *xgb.Conn, Drawable Drawable, Context Context, OldContextTag ContextTag) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], uint32(OldContextTag)) + b += 4 + + return buf +} + +// NewListCookie is a cookie used only for NewList requests. +type NewListCookie struct { + *xgb.Cookie +} + +// NewList sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func NewList(c *xgb.Conn, ContextTag ContextTag, List uint32, Mode uint32) NewListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'NewList' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(newListRequest(c, ContextTag, List, Mode), cookie) + return NewListCookie{cookie} +} + +// NewListChecked sends a checked request. +// If an error occurs, it can be retrieved using NewListCookie.Check() +func NewListChecked(c *xgb.Conn, ContextTag ContextTag, List uint32, Mode uint32) NewListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'NewList' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(newListRequest(c, ContextTag, List, Mode), cookie) + return NewListCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook NewListCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for NewList +// newListRequest writes a NewList request to a byte slice. +func newListRequest(c *xgb.Conn, ContextTag ContextTag, List uint32, Mode uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 101 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], List) + b += 4 + + xgb.Put32(buf[b:], Mode) + b += 4 + + return buf +} + +// PixelStorefCookie is a cookie used only for PixelStoref requests. +type PixelStorefCookie struct { + *xgb.Cookie +} + +// PixelStoref sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PixelStoref(c *xgb.Conn, ContextTag ContextTag, Pname uint32, Datum Float32) PixelStorefCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'PixelStoref' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(pixelStorefRequest(c, ContextTag, Pname, Datum), cookie) + return PixelStorefCookie{cookie} +} + +// PixelStorefChecked sends a checked request. +// If an error occurs, it can be retrieved using PixelStorefCookie.Check() +func PixelStorefChecked(c *xgb.Conn, ContextTag ContextTag, Pname uint32, Datum Float32) PixelStorefCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'PixelStoref' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(pixelStorefRequest(c, ContextTag, Pname, Datum), cookie) + return PixelStorefCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PixelStorefCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PixelStoref +// pixelStorefRequest writes a PixelStoref request to a byte slice. +func pixelStorefRequest(c *xgb.Conn, ContextTag ContextTag, Pname uint32, Datum Float32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 109 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + xgb.Put32(buf[b:], uint32(Datum)) + b += 4 + + return buf +} + +// PixelStoreiCookie is a cookie used only for PixelStorei requests. +type PixelStoreiCookie struct { + *xgb.Cookie +} + +// PixelStorei sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PixelStorei(c *xgb.Conn, ContextTag ContextTag, Pname uint32, Datum int32) PixelStoreiCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'PixelStorei' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(pixelStoreiRequest(c, ContextTag, Pname, Datum), cookie) + return PixelStoreiCookie{cookie} +} + +// PixelStoreiChecked sends a checked request. +// If an error occurs, it can be retrieved using PixelStoreiCookie.Check() +func PixelStoreiChecked(c *xgb.Conn, ContextTag ContextTag, Pname uint32, Datum int32) PixelStoreiCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'PixelStorei' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(pixelStoreiRequest(c, ContextTag, Pname, Datum), cookie) + return PixelStoreiCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PixelStoreiCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PixelStorei +// pixelStoreiRequest writes a PixelStorei request to a byte slice. +func pixelStoreiRequest(c *xgb.Conn, ContextTag ContextTag, Pname uint32, Datum int32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 110 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Pname) + b += 4 + + xgb.Put32(buf[b:], uint32(Datum)) + b += 4 + + return buf +} + +// QueryContextCookie is a cookie used only for QueryContext requests. +type QueryContextCookie struct { + *xgb.Cookie +} + +// QueryContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryContextCookie.Reply() +func QueryContext(c *xgb.Conn, Context Context) QueryContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryContextRequest(c, Context), cookie) + return QueryContextCookie{cookie} +} + +// QueryContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryContextUnchecked(c *xgb.Conn, Context Context) QueryContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryContext' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryContextRequest(c, Context), cookie) + return QueryContextCookie{cookie} +} + +// QueryContextReply represents the data returned from a QueryContext request. +type QueryContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAttribs uint32 + // padding: 20 bytes + Attribs []uint32 // size: xgb.Pad(((int(NumAttribs) * 2) * 4)) +} + +// Reply blocks and returns the reply data for a QueryContext request. +func (cook QueryContextCookie) Reply() (*QueryContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryContextReply(buf), nil +} + +// queryContextReply reads a byte slice into a QueryContextReply value. +func queryContextReply(buf []byte) *QueryContextReply { + v := new(QueryContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAttribs = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Attribs = make([]uint32, (int(v.NumAttribs) * 2)) + for i := 0; i < int((int(v.NumAttribs) * 2)); i++ { + v.Attribs[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for QueryContext +// queryContextRequest writes a QueryContext request to a byte slice. +func queryContextRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 25 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// QueryExtensionsStringCookie is a cookie used only for QueryExtensionsString requests. +type QueryExtensionsStringCookie struct { + *xgb.Cookie +} + +// QueryExtensionsString sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryExtensionsStringCookie.Reply() +func QueryExtensionsString(c *xgb.Conn, Screen uint32) QueryExtensionsStringCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryExtensionsString' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryExtensionsStringRequest(c, Screen), cookie) + return QueryExtensionsStringCookie{cookie} +} + +// QueryExtensionsStringUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryExtensionsStringUnchecked(c *xgb.Conn, Screen uint32) QueryExtensionsStringCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryExtensionsString' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryExtensionsStringRequest(c, Screen), cookie) + return QueryExtensionsStringCookie{cookie} +} + +// QueryExtensionsStringReply represents the data returned from a QueryExtensionsString request. +type QueryExtensionsStringReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + N uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryExtensionsString request. +func (cook QueryExtensionsStringCookie) Reply() (*QueryExtensionsStringReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryExtensionsStringReply(buf), nil +} + +// queryExtensionsStringReply reads a byte slice into a QueryExtensionsStringReply value. +func queryExtensionsStringReply(buf []byte) *QueryExtensionsStringReply { + v := new(QueryExtensionsStringReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.N = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryExtensionsString +// queryExtensionsStringRequest writes a QueryExtensionsString request to a byte slice. +func queryExtensionsStringRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// QueryServerStringCookie is a cookie used only for QueryServerString requests. +type QueryServerStringCookie struct { + *xgb.Cookie +} + +// QueryServerString sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryServerStringCookie.Reply() +func QueryServerString(c *xgb.Conn, Screen uint32, Name uint32) QueryServerStringCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryServerString' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryServerStringRequest(c, Screen, Name), cookie) + return QueryServerStringCookie{cookie} +} + +// QueryServerStringUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryServerStringUnchecked(c *xgb.Conn, Screen uint32, Name uint32) QueryServerStringCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryServerString' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryServerStringRequest(c, Screen, Name), cookie) + return QueryServerStringCookie{cookie} +} + +// QueryServerStringReply represents the data returned from a QueryServerString request. +type QueryServerStringReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 4 bytes + StrLen uint32 + // padding: 16 bytes + String string // size: xgb.Pad((int(StrLen) * 1)) +} + +// Reply blocks and returns the reply data for a QueryServerString request. +func (cook QueryServerStringCookie) Reply() (*QueryServerStringReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryServerStringReply(buf), nil +} + +// queryServerStringReply reads a byte slice into a QueryServerStringReply value. +func queryServerStringReply(buf []byte) *QueryServerStringReply { + v := new(QueryServerStringReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 4 // padding + + v.StrLen = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + { + byteString := make([]byte, v.StrLen) + copy(byteString[:v.StrLen], buf[b:]) + v.String = string(byteString) + b += int(v.StrLen) + } + + return v +} + +// Write request to wire for QueryServerString +// queryServerStringRequest writes a QueryServerString request to a byte slice. +func queryServerStringRequest(c *xgb.Conn, Screen uint32, Name uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Name) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + return buf +} + +// ReadPixelsCookie is a cookie used only for ReadPixels requests. +type ReadPixelsCookie struct { + *xgb.Cookie +} + +// ReadPixels sends a checked request. +// If an error occurs, it will be returned with the reply by calling ReadPixelsCookie.Reply() +func ReadPixels(c *xgb.Conn, ContextTag ContextTag, X int32, Y int32, Width int32, Height int32, Format uint32, Type uint32, SwapBytes bool, LsbFirst bool) ReadPixelsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'ReadPixels' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(readPixelsRequest(c, ContextTag, X, Y, Width, Height, Format, Type, SwapBytes, LsbFirst), cookie) + return ReadPixelsCookie{cookie} +} + +// ReadPixelsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ReadPixelsUnchecked(c *xgb.Conn, ContextTag ContextTag, X int32, Y int32, Width int32, Height int32, Format uint32, Type uint32, SwapBytes bool, LsbFirst bool) ReadPixelsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'ReadPixels' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(readPixelsRequest(c, ContextTag, X, Y, Width, Height, Format, Type, SwapBytes, LsbFirst), cookie) + return ReadPixelsCookie{cookie} +} + +// ReadPixelsReply represents the data returned from a ReadPixels request. +type ReadPixelsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a ReadPixels request. +func (cook ReadPixelsCookie) Reply() (*ReadPixelsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return readPixelsReply(buf), nil +} + +// readPixelsReply reads a byte slice into a ReadPixelsReply value. +func readPixelsReply(buf []byte) *ReadPixelsReply { + v := new(ReadPixelsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for ReadPixels +// readPixelsRequest writes a ReadPixels request to a byte slice. +func readPixelsRequest(c *xgb.Conn, ContextTag ContextTag, X int32, Y int32, Width int32, Height int32, Format uint32, Type uint32, SwapBytes bool, LsbFirst bool) []byte { + size := 36 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 111 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(X)) + b += 4 + + xgb.Put32(buf[b:], uint32(Y)) + b += 4 + + xgb.Put32(buf[b:], uint32(Width)) + b += 4 + + xgb.Put32(buf[b:], uint32(Height)) + b += 4 + + xgb.Put32(buf[b:], Format) + b += 4 + + xgb.Put32(buf[b:], Type) + b += 4 + + if SwapBytes { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if LsbFirst { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// RenderCookie is a cookie used only for Render requests. +type RenderCookie struct { + *xgb.Cookie +} + +// Render sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Render(c *xgb.Conn, ContextTag ContextTag, Data []byte) RenderCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'Render' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(renderRequest(c, ContextTag, Data), cookie) + return RenderCookie{cookie} +} + +// RenderChecked sends a checked request. +// If an error occurs, it can be retrieved using RenderCookie.Check() +func RenderChecked(c *xgb.Conn, ContextTag ContextTag, Data []byte) RenderCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'Render' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(renderRequest(c, ContextTag, Data), cookie) + return RenderCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RenderCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Render +// renderRequest writes a Render request to a byte slice. +func renderRequest(c *xgb.Conn, ContextTag ContextTag, Data []byte) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Data) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + copy(buf[b:], Data[:len(Data)]) + b += int(len(Data)) + + return buf +} + +// RenderLargeCookie is a cookie used only for RenderLarge requests. +type RenderLargeCookie struct { + *xgb.Cookie +} + +// RenderLarge sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RenderLarge(c *xgb.Conn, ContextTag ContextTag, RequestNum uint16, RequestTotal uint16, DataLen uint32, Data []byte) RenderLargeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'RenderLarge' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(renderLargeRequest(c, ContextTag, RequestNum, RequestTotal, DataLen, Data), cookie) + return RenderLargeCookie{cookie} +} + +// RenderLargeChecked sends a checked request. +// If an error occurs, it can be retrieved using RenderLargeCookie.Check() +func RenderLargeChecked(c *xgb.Conn, ContextTag ContextTag, RequestNum uint16, RequestTotal uint16, DataLen uint32, Data []byte) RenderLargeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'RenderLarge' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(renderLargeRequest(c, ContextTag, RequestNum, RequestTotal, DataLen, Data), cookie) + return RenderLargeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RenderLargeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RenderLarge +// renderLargeRequest writes a RenderLarge request to a byte slice. +func renderLargeRequest(c *xgb.Conn, ContextTag ContextTag, RequestNum uint16, RequestTotal uint16, DataLen uint32, Data []byte) []byte { + size := xgb.Pad((16 + xgb.Pad((int(DataLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put16(buf[b:], RequestNum) + b += 2 + + xgb.Put16(buf[b:], RequestTotal) + b += 2 + + xgb.Put32(buf[b:], DataLen) + b += 4 + + copy(buf[b:], Data[:DataLen]) + b += int(DataLen) + + return buf +} + +// RenderModeCookie is a cookie used only for RenderMode requests. +type RenderModeCookie struct { + *xgb.Cookie +} + +// RenderMode sends a checked request. +// If an error occurs, it will be returned with the reply by calling RenderModeCookie.Reply() +func RenderMode(c *xgb.Conn, ContextTag ContextTag, Mode uint32) RenderModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'RenderMode' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(renderModeRequest(c, ContextTag, Mode), cookie) + return RenderModeCookie{cookie} +} + +// RenderModeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RenderModeUnchecked(c *xgb.Conn, ContextTag ContextTag, Mode uint32) RenderModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'RenderMode' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(renderModeRequest(c, ContextTag, Mode), cookie) + return RenderModeCookie{cookie} +} + +// RenderModeReply represents the data returned from a RenderMode request. +type RenderModeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal uint32 + N uint32 + NewMode uint32 + // padding: 12 bytes + Data []uint32 // size: xgb.Pad((int(N) * 4)) +} + +// Reply blocks and returns the reply data for a RenderMode request. +func (cook RenderModeCookie) Reply() (*RenderModeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return renderModeReply(buf), nil +} + +// renderModeReply reads a byte slice into a RenderModeReply value. +func renderModeReply(buf []byte) *RenderModeReply { + v := new(RenderModeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = xgb.Get32(buf[b:]) + b += 4 + + v.N = xgb.Get32(buf[b:]) + b += 4 + + v.NewMode = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Data = make([]uint32, v.N) + for i := 0; i < int(v.N); i++ { + v.Data[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for RenderMode +// renderModeRequest writes a RenderMode request to a byte slice. +func renderModeRequest(c *xgb.Conn, ContextTag ContextTag, Mode uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 107 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Mode) + b += 4 + + return buf +} + +// SelectBufferCookie is a cookie used only for SelectBuffer requests. +type SelectBufferCookie struct { + *xgb.Cookie +} + +// SelectBuffer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectBuffer(c *xgb.Conn, ContextTag ContextTag, Size int32) SelectBufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SelectBuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectBufferRequest(c, ContextTag, Size), cookie) + return SelectBufferCookie{cookie} +} + +// SelectBufferChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectBufferCookie.Check() +func SelectBufferChecked(c *xgb.Conn, ContextTag ContextTag, Size int32) SelectBufferCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SelectBuffer' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectBufferRequest(c, ContextTag, Size), cookie) + return SelectBufferCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectBufferCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectBuffer +// selectBufferRequest writes a SelectBuffer request to a byte slice. +func selectBufferRequest(c *xgb.Conn, ContextTag ContextTag, Size int32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 106 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Size)) + b += 4 + + return buf +} + +// SetClientInfo2ARBCookie is a cookie used only for SetClientInfo2ARB requests. +type SetClientInfo2ARBCookie struct { + *xgb.Cookie +} + +// SetClientInfo2ARB sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetClientInfo2ARB(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) SetClientInfo2ARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SetClientInfo2ARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setClientInfo2ARBRequest(c, MajorVersion, MinorVersion, NumVersions, GlStrLen, GlxStrLen, GlVersions, GlExtensionString, GlxExtensionString), cookie) + return SetClientInfo2ARBCookie{cookie} +} + +// SetClientInfo2ARBChecked sends a checked request. +// If an error occurs, it can be retrieved using SetClientInfo2ARBCookie.Check() +func SetClientInfo2ARBChecked(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) SetClientInfo2ARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SetClientInfo2ARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setClientInfo2ARBRequest(c, MajorVersion, MinorVersion, NumVersions, GlStrLen, GlxStrLen, GlVersions, GlExtensionString, GlxExtensionString), cookie) + return SetClientInfo2ARBCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetClientInfo2ARBCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetClientInfo2ARB +// setClientInfo2ARBRequest writes a SetClientInfo2ARB request to a byte slice. +func setClientInfo2ARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) []byte { + size := xgb.Pad(((((24 + xgb.Pad(((int(NumVersions) * 3) * 4))) + xgb.Pad((int(GlStrLen) * 1))) + 4) + xgb.Pad((int(GlxStrLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 35 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + xgb.Put32(buf[b:], NumVersions) + b += 4 + + xgb.Put32(buf[b:], GlStrLen) + b += 4 + + xgb.Put32(buf[b:], GlxStrLen) + b += 4 + + for i := 0; i < int((int(NumVersions) * 3)); i++ { + xgb.Put32(buf[b:], GlVersions[i]) + b += 4 + } + + copy(buf[b:], GlExtensionString[:GlStrLen]) + b += int(GlStrLen) + + b = (b + 3) & ^3 // alignment gap + + copy(buf[b:], GlxExtensionString[:GlxStrLen]) + b += int(GlxStrLen) + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// SetClientInfoARBCookie is a cookie used only for SetClientInfoARB requests. +type SetClientInfoARBCookie struct { + *xgb.Cookie +} + +// SetClientInfoARB sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetClientInfoARB(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) SetClientInfoARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SetClientInfoARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setClientInfoARBRequest(c, MajorVersion, MinorVersion, NumVersions, GlStrLen, GlxStrLen, GlVersions, GlExtensionString, GlxExtensionString), cookie) + return SetClientInfoARBCookie{cookie} +} + +// SetClientInfoARBChecked sends a checked request. +// If an error occurs, it can be retrieved using SetClientInfoARBCookie.Check() +func SetClientInfoARBChecked(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) SetClientInfoARBCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SetClientInfoARB' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setClientInfoARBRequest(c, MajorVersion, MinorVersion, NumVersions, GlStrLen, GlxStrLen, GlVersions, GlExtensionString, GlxExtensionString), cookie) + return SetClientInfoARBCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetClientInfoARBCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetClientInfoARB +// setClientInfoARBRequest writes a SetClientInfoARB request to a byte slice. +func setClientInfoARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) []byte { + size := xgb.Pad(((((24 + xgb.Pad(((int(NumVersions) * 2) * 4))) + xgb.Pad((int(GlStrLen) * 1))) + 4) + xgb.Pad((int(GlxStrLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 33 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + xgb.Put32(buf[b:], NumVersions) + b += 4 + + xgb.Put32(buf[b:], GlStrLen) + b += 4 + + xgb.Put32(buf[b:], GlxStrLen) + b += 4 + + for i := 0; i < int((int(NumVersions) * 2)); i++ { + xgb.Put32(buf[b:], GlVersions[i]) + b += 4 + } + + copy(buf[b:], GlExtensionString[:GlStrLen]) + b += int(GlStrLen) + + b = (b + 3) & ^3 // alignment gap + + copy(buf[b:], GlxExtensionString[:GlxStrLen]) + b += int(GlxStrLen) + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// SwapBuffersCookie is a cookie used only for SwapBuffers requests. +type SwapBuffersCookie struct { + *xgb.Cookie +} + +// SwapBuffers sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwapBuffers(c *xgb.Conn, ContextTag ContextTag, Drawable Drawable) SwapBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SwapBuffers' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(swapBuffersRequest(c, ContextTag, Drawable), cookie) + return SwapBuffersCookie{cookie} +} + +// SwapBuffersChecked sends a checked request. +// If an error occurs, it can be retrieved using SwapBuffersCookie.Check() +func SwapBuffersChecked(c *xgb.Conn, ContextTag ContextTag, Drawable Drawable) SwapBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'SwapBuffers' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(swapBuffersRequest(c, ContextTag, Drawable), cookie) + return SwapBuffersCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SwapBuffersCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SwapBuffers +// swapBuffersRequest writes a SwapBuffers request to a byte slice. +func swapBuffersRequest(c *xgb.Conn, ContextTag ContextTag, Drawable Drawable) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// UseXFontCookie is a cookie used only for UseXFont requests. +type UseXFontCookie struct { + *xgb.Cookie +} + +// UseXFont sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UseXFont(c *xgb.Conn, ContextTag ContextTag, Font xproto.Font, First uint32, Count uint32, ListBase uint32) UseXFontCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'UseXFont' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(useXFontRequest(c, ContextTag, Font, First, Count, ListBase), cookie) + return UseXFontCookie{cookie} +} + +// UseXFontChecked sends a checked request. +// If an error occurs, it can be retrieved using UseXFontCookie.Check() +func UseXFontChecked(c *xgb.Conn, ContextTag ContextTag, Font xproto.Font, First uint32, Count uint32, ListBase uint32) UseXFontCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'UseXFont' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(useXFontRequest(c, ContextTag, Font, First, Count, ListBase), cookie) + return UseXFontCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UseXFontCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UseXFont +// useXFontRequest writes a UseXFont request to a byte slice. +func useXFontRequest(c *xgb.Conn, ContextTag ContextTag, Font xproto.Font, First uint32, Count uint32, ListBase uint32) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], uint32(Font)) + b += 4 + + xgb.Put32(buf[b:], First) + b += 4 + + xgb.Put32(buf[b:], Count) + b += 4 + + xgb.Put32(buf[b:], ListBase) + b += 4 + + return buf +} + +// VendorPrivateCookie is a cookie used only for VendorPrivate requests. +type VendorPrivateCookie struct { + *xgb.Cookie +} + +// VendorPrivate sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func VendorPrivate(c *xgb.Conn, VendorCode uint32, ContextTag ContextTag, Data []byte) VendorPrivateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'VendorPrivate' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(vendorPrivateRequest(c, VendorCode, ContextTag, Data), cookie) + return VendorPrivateCookie{cookie} +} + +// VendorPrivateChecked sends a checked request. +// If an error occurs, it can be retrieved using VendorPrivateCookie.Check() +func VendorPrivateChecked(c *xgb.Conn, VendorCode uint32, ContextTag ContextTag, Data []byte) VendorPrivateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'VendorPrivate' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(vendorPrivateRequest(c, VendorCode, ContextTag, Data), cookie) + return VendorPrivateCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook VendorPrivateCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for VendorPrivate +// vendorPrivateRequest writes a VendorPrivate request to a byte slice. +func vendorPrivateRequest(c *xgb.Conn, VendorCode uint32, ContextTag ContextTag, Data []byte) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Data) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], VendorCode) + b += 4 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + copy(buf[b:], Data[:len(Data)]) + b += int(len(Data)) + + return buf +} + +// VendorPrivateWithReplyCookie is a cookie used only for VendorPrivateWithReply requests. +type VendorPrivateWithReplyCookie struct { + *xgb.Cookie +} + +// VendorPrivateWithReply sends a checked request. +// If an error occurs, it will be returned with the reply by calling VendorPrivateWithReplyCookie.Reply() +func VendorPrivateWithReply(c *xgb.Conn, VendorCode uint32, ContextTag ContextTag, Data []byte) VendorPrivateWithReplyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'VendorPrivateWithReply' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(vendorPrivateWithReplyRequest(c, VendorCode, ContextTag, Data), cookie) + return VendorPrivateWithReplyCookie{cookie} +} + +// VendorPrivateWithReplyUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func VendorPrivateWithReplyUnchecked(c *xgb.Conn, VendorCode uint32, ContextTag ContextTag, Data []byte) VendorPrivateWithReplyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'VendorPrivateWithReply' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(vendorPrivateWithReplyRequest(c, VendorCode, ContextTag, Data), cookie) + return VendorPrivateWithReplyCookie{cookie} +} + +// VendorPrivateWithReplyReply represents the data returned from a VendorPrivateWithReply request. +type VendorPrivateWithReplyReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Retval uint32 + Data1 []byte // size: 24 + Data2 []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a VendorPrivateWithReply request. +func (cook VendorPrivateWithReplyCookie) Reply() (*VendorPrivateWithReplyReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return vendorPrivateWithReplyReply(buf), nil +} + +// vendorPrivateWithReplyReply reads a byte slice into a VendorPrivateWithReplyReply value. +func vendorPrivateWithReplyReply(buf []byte) *VendorPrivateWithReplyReply { + v := new(VendorPrivateWithReplyReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Retval = xgb.Get32(buf[b:]) + b += 4 + + v.Data1 = make([]byte, 24) + copy(v.Data1[:24], buf[b:]) + b += int(24) + + v.Data2 = make([]byte, (int(v.Length) * 4)) + copy(v.Data2[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for VendorPrivateWithReply +// vendorPrivateWithReplyRequest writes a VendorPrivateWithReply request to a byte slice. +func vendorPrivateWithReplyRequest(c *xgb.Conn, VendorCode uint32, ContextTag ContextTag, Data []byte) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Data) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], VendorCode) + b += 4 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + copy(buf[b:], Data[:len(Data)]) + b += int(len(Data)) + + return buf +} + +// WaitGLCookie is a cookie used only for WaitGL requests. +type WaitGLCookie struct { + *xgb.Cookie +} + +// WaitGL sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WaitGL(c *xgb.Conn, ContextTag ContextTag) WaitGLCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'WaitGL' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(waitGLRequest(c, ContextTag), cookie) + return WaitGLCookie{cookie} +} + +// WaitGLChecked sends a checked request. +// If an error occurs, it can be retrieved using WaitGLCookie.Check() +func WaitGLChecked(c *xgb.Conn, ContextTag ContextTag) WaitGLCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'WaitGL' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(waitGLRequest(c, ContextTag), cookie) + return WaitGLCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook WaitGLCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for WaitGL +// waitGLRequest writes a WaitGL request to a byte slice. +func waitGLRequest(c *xgb.Conn, ContextTag ContextTag) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + return buf +} + +// WaitXCookie is a cookie used only for WaitX requests. +type WaitXCookie struct { + *xgb.Cookie +} + +// WaitX sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WaitX(c *xgb.Conn, ContextTag ContextTag) WaitXCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'WaitX' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(waitXRequest(c, ContextTag), cookie) + return WaitXCookie{cookie} +} + +// WaitXChecked sends a checked request. +// If an error occurs, it can be retrieved using WaitXCookie.Check() +func WaitXChecked(c *xgb.Conn, ContextTag ContextTag) WaitXCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'WaitX' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(waitXRequest(c, ContextTag), cookie) + return WaitXCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook WaitXCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for WaitX +// waitXRequest writes a WaitX request to a byte slice. +func waitXRequest(c *xgb.Conn, ContextTag ContextTag) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + return buf +} diff --git a/vend/xgb/go.mod b/vend/xgb/go.mod new file mode 100644 index 0000000..25750d9 --- /dev/null +++ b/vend/xgb/go.mod @@ -0,0 +1,3 @@ +module github.com/jezek/xgb + +go 1.11 diff --git a/vend/xgb/help.go b/vend/xgb/help.go new file mode 100644 index 0000000..f692442 --- /dev/null +++ b/vend/xgb/help.go @@ -0,0 +1,105 @@ +package xgb + +/* +help.go is meant to contain a rough hodge podge of functions that are mainly +used in the auto generated code. Indeed, several functions here are simple +wrappers so that the sub-packages don't need to be smart about which stdlib +packages to import. + +Also, the 'Get..' and 'Put..' functions are used through the core xgb package +too. (xgbutil uses them too.) +*/ + +import ( + "fmt" + "strings" +) + +// StringsJoin is an alias to strings.Join. It allows us to avoid having to +// import 'strings' in each of the generated Go files. +func StringsJoin(ss []string, sep string) string { + return strings.Join(ss, sep) +} + +// Sprintf is so we don't need to import 'fmt' in the generated Go files. +func Sprintf(format string, v ...interface{}) string { + return fmt.Sprintf(format, v...) +} + +// Errorf is just a wrapper for fmt.Errorf. Exists for the same reason +// that 'stringsJoin' and 'sprintf' exists. +func Errorf(format string, v ...interface{}) error { + return fmt.Errorf(format, v...) +} + +// Pad a length to align on 4 bytes. +func Pad(n int) int { + return (n + 3) & ^3 +} + +// PopCount counts the number of bits set in a value list mask. +func PopCount(mask0 int) int { + mask := uint32(mask0) + n := 0 + for i := uint32(0); i < 32; i++ { + if mask&(1<> 8) +} + +// Put32 takes a 32 bit integer and copies it into a byte slice. +func Put32(buf []byte, v uint32) { + buf[0] = byte(v) + buf[1] = byte(v >> 8) + buf[2] = byte(v >> 16) + buf[3] = byte(v >> 24) +} + +// Put64 takes a 64 bit integer and copies it into a byte slice. +func Put64(buf []byte, v uint64) { + buf[0] = byte(v) + buf[1] = byte(v >> 8) + buf[2] = byte(v >> 16) + buf[3] = byte(v >> 24) + buf[4] = byte(v >> 32) + buf[5] = byte(v >> 40) + buf[6] = byte(v >> 48) + buf[7] = byte(v >> 56) +} + +// Get16 constructs a 16 bit integer from the beginning of a byte slice. +func Get16(buf []byte) uint16 { + v := uint16(buf[0]) + v |= uint16(buf[1]) << 8 + return v +} + +// Get32 constructs a 32 bit integer from the beginning of a byte slice. +func Get32(buf []byte) uint32 { + v := uint32(buf[0]) + v |= uint32(buf[1]) << 8 + v |= uint32(buf[2]) << 16 + v |= uint32(buf[3]) << 24 + return v +} + +// Get64 constructs a 64 bit integer from the beginning of a byte slice. +func Get64(buf []byte) uint64 { + v := uint64(buf[0]) + v |= uint64(buf[1]) << 8 + v |= uint64(buf[2]) << 16 + v |= uint64(buf[3]) << 24 + v |= uint64(buf[4]) << 32 + v |= uint64(buf[5]) << 40 + v |= uint64(buf[6]) << 48 + v |= uint64(buf[7]) << 56 + return v +} diff --git a/vend/xgb/randr/randr.go b/vend/xgb/randr/randr.go new file mode 100644 index 0000000..2944f68 --- /dev/null +++ b/vend/xgb/randr/randr.go @@ -0,0 +1,6607 @@ +// Package randr is the X client API for the RANDR extension. +package randr + +// This file is automatically generated from randr.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/render" + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the RANDR extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 5, "RANDR").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named RANDR could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["RANDR"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["RANDR"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["RANDR"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["RANDR"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["RANDR"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadCrtc is the error number for a BadBadCrtc. +const BadBadCrtc = 1 + +type BadCrtcError struct { + Sequence uint16 + NiceName string +} + +// BadCrtcErrorNew constructs a BadCrtcError value that implements xgb.Error from a byte slice. +func BadCrtcErrorNew(buf []byte) xgb.Error { + v := BadCrtcError{} + v.NiceName = "BadCrtc" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadCrtc error. +// This is mostly used internally. +func (err BadCrtcError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadCrtc error. If no bad value exists, 0 is returned. +func (err BadCrtcError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadCrtc error. + +func (err BadCrtcError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadCrtc {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RANDR"][1] = BadCrtcErrorNew +} + +// BadBadMode is the error number for a BadBadMode. +const BadBadMode = 2 + +type BadModeError struct { + Sequence uint16 + NiceName string +} + +// BadModeErrorNew constructs a BadModeError value that implements xgb.Error from a byte slice. +func BadModeErrorNew(buf []byte) xgb.Error { + v := BadModeError{} + v.NiceName = "BadMode" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadMode error. +// This is mostly used internally. +func (err BadModeError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadMode error. If no bad value exists, 0 is returned. +func (err BadModeError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadMode error. + +func (err BadModeError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadMode {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RANDR"][2] = BadModeErrorNew +} + +// BadBadOutput is the error number for a BadBadOutput. +const BadBadOutput = 0 + +type BadOutputError struct { + Sequence uint16 + NiceName string +} + +// BadOutputErrorNew constructs a BadOutputError value that implements xgb.Error from a byte slice. +func BadOutputErrorNew(buf []byte) xgb.Error { + v := BadOutputError{} + v.NiceName = "BadOutput" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadOutput error. +// This is mostly used internally. +func (err BadOutputError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadOutput error. If no bad value exists, 0 is returned. +func (err BadOutputError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadOutput error. + +func (err BadOutputError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadOutput {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RANDR"][0] = BadOutputErrorNew +} + +// BadBadProvider is the error number for a BadBadProvider. +const BadBadProvider = 3 + +type BadProviderError struct { + Sequence uint16 + NiceName string +} + +// BadProviderErrorNew constructs a BadProviderError value that implements xgb.Error from a byte slice. +func BadProviderErrorNew(buf []byte) xgb.Error { + v := BadProviderError{} + v.NiceName = "BadProvider" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadProvider error. +// This is mostly used internally. +func (err BadProviderError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadProvider error. If no bad value exists, 0 is returned. +func (err BadProviderError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadProvider error. + +func (err BadProviderError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadProvider {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RANDR"][3] = BadProviderErrorNew +} + +const ( + ConnectionConnected = 0 + ConnectionDisconnected = 1 + ConnectionUnknown = 2 +) + +type Crtc uint32 + +func NewCrtcId(c *xgb.Conn) (Crtc, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Crtc(id), nil +} + +type CrtcChange struct { + Timestamp xproto.Timestamp + Window xproto.Window + Crtc Crtc + Mode Mode + Rotation uint16 + // padding: 2 bytes + X int16 + Y int16 + Width uint16 + Height uint16 +} + +// CrtcChangeRead reads a byte slice into a CrtcChange value. +func CrtcChangeRead(buf []byte, v *CrtcChange) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Crtc = Crtc(xgb.Get32(buf[b:])) + b += 4 + + v.Mode = Mode(xgb.Get32(buf[b:])) + b += 4 + + v.Rotation = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// CrtcChangeReadList reads a byte slice into a list of CrtcChange values. +func CrtcChangeReadList(buf []byte, dest []CrtcChange) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = CrtcChange{} + b += CrtcChangeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a CrtcChange value to a byte slice. +func (v CrtcChange) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Crtc)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Mode)) + b += 4 + + xgb.Put16(buf[b:], v.Rotation) + b += 2 + + b += 2 // padding + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + return buf[:b] +} + +// CrtcChangeListBytes writes a list of CrtcChange values to a byte slice. +func CrtcChangeListBytes(buf []byte, list []CrtcChange) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Lease uint32 + +func NewLeaseId(c *xgb.Conn) (Lease, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Lease(id), nil +} + +type LeaseNotify struct { + Timestamp xproto.Timestamp + Window xproto.Window + Lease Lease + Created byte + // padding: 15 bytes +} + +// LeaseNotifyRead reads a byte slice into a LeaseNotify value. +func LeaseNotifyRead(buf []byte, v *LeaseNotify) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Lease = Lease(xgb.Get32(buf[b:])) + b += 4 + + v.Created = buf[b] + b += 1 + + b += 15 // padding + + return b +} + +// LeaseNotifyReadList reads a byte slice into a list of LeaseNotify values. +func LeaseNotifyReadList(buf []byte, dest []LeaseNotify) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a LeaseNotify value to a byte slice. +func (v LeaseNotify) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Lease)) + b += 4 + + buf[b] = v.Created + b += 1 + + b += 15 // padding + + return buf[:b] +} + +// LeaseNotifyListBytes writes a list of LeaseNotify values to a byte slice. +func LeaseNotifyListBytes(buf []byte, list []LeaseNotify) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Mode uint32 + +func NewModeId(c *xgb.Conn) (Mode, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Mode(id), nil +} + +const ( + ModeFlagHsyncPositive = 1 + ModeFlagHsyncNegative = 2 + ModeFlagVsyncPositive = 4 + ModeFlagVsyncNegative = 8 + ModeFlagInterlace = 16 + ModeFlagDoubleScan = 32 + ModeFlagCsync = 64 + ModeFlagCsyncPositive = 128 + ModeFlagCsyncNegative = 256 + ModeFlagHskewPresent = 512 + ModeFlagBcast = 1024 + ModeFlagPixelMultiplex = 2048 + ModeFlagDoubleClock = 4096 + ModeFlagHalveClock = 8192 +) + +type ModeInfo struct { + Id uint32 + Width uint16 + Height uint16 + DotClock uint32 + HsyncStart uint16 + HsyncEnd uint16 + Htotal uint16 + Hskew uint16 + VsyncStart uint16 + VsyncEnd uint16 + Vtotal uint16 + NameLen uint16 + ModeFlags uint32 +} + +// ModeInfoRead reads a byte slice into a ModeInfo value. +func ModeInfoRead(buf []byte, v *ModeInfo) int { + b := 0 + + v.Id = xgb.Get32(buf[b:]) + b += 4 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.DotClock = xgb.Get32(buf[b:]) + b += 4 + + v.HsyncStart = xgb.Get16(buf[b:]) + b += 2 + + v.HsyncEnd = xgb.Get16(buf[b:]) + b += 2 + + v.Htotal = xgb.Get16(buf[b:]) + b += 2 + + v.Hskew = xgb.Get16(buf[b:]) + b += 2 + + v.VsyncStart = xgb.Get16(buf[b:]) + b += 2 + + v.VsyncEnd = xgb.Get16(buf[b:]) + b += 2 + + v.Vtotal = xgb.Get16(buf[b:]) + b += 2 + + v.NameLen = xgb.Get16(buf[b:]) + b += 2 + + v.ModeFlags = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// ModeInfoReadList reads a byte slice into a list of ModeInfo values. +func ModeInfoReadList(buf []byte, dest []ModeInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ModeInfo{} + b += ModeInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ModeInfo value to a byte slice. +func (v ModeInfo) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + xgb.Put32(buf[b:], v.Id) + b += 4 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put32(buf[b:], v.DotClock) + b += 4 + + xgb.Put16(buf[b:], v.HsyncStart) + b += 2 + + xgb.Put16(buf[b:], v.HsyncEnd) + b += 2 + + xgb.Put16(buf[b:], v.Htotal) + b += 2 + + xgb.Put16(buf[b:], v.Hskew) + b += 2 + + xgb.Put16(buf[b:], v.VsyncStart) + b += 2 + + xgb.Put16(buf[b:], v.VsyncEnd) + b += 2 + + xgb.Put16(buf[b:], v.Vtotal) + b += 2 + + xgb.Put16(buf[b:], v.NameLen) + b += 2 + + xgb.Put32(buf[b:], v.ModeFlags) + b += 4 + + return buf[:b] +} + +// ModeInfoListBytes writes a list of ModeInfo values to a byte slice. +func ModeInfoListBytes(buf []byte, list []ModeInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type MonitorInfo struct { + Name xproto.Atom + Primary bool + Automatic bool + NOutput uint16 + X int16 + Y int16 + Width uint16 + Height uint16 + WidthInMillimeters uint32 + HeightInMillimeters uint32 + Outputs []Output // size: xgb.Pad((int(NOutput) * 4)) +} + +// MonitorInfoRead reads a byte slice into a MonitorInfo value. +func MonitorInfoRead(buf []byte, v *MonitorInfo) int { + b := 0 + + v.Name = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.Primary = true + } else { + v.Primary = false + } + b += 1 + + if buf[b] == 1 { + v.Automatic = true + } else { + v.Automatic = false + } + b += 1 + + v.NOutput = xgb.Get16(buf[b:]) + b += 2 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.WidthInMillimeters = xgb.Get32(buf[b:]) + b += 4 + + v.HeightInMillimeters = xgb.Get32(buf[b:]) + b += 4 + + v.Outputs = make([]Output, v.NOutput) + for i := 0; i < int(v.NOutput); i++ { + v.Outputs[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + return b +} + +// MonitorInfoReadList reads a byte slice into a list of MonitorInfo values. +func MonitorInfoReadList(buf []byte, dest []MonitorInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = MonitorInfo{} + b += MonitorInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a MonitorInfo value to a byte slice. +func (v MonitorInfo) Bytes() []byte { + buf := make([]byte, (24 + xgb.Pad((int(v.NOutput) * 4)))) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Name)) + b += 4 + + if v.Primary { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if v.Automatic { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], v.NOutput) + b += 2 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put32(buf[b:], v.WidthInMillimeters) + b += 4 + + xgb.Put32(buf[b:], v.HeightInMillimeters) + b += 4 + + for i := 0; i < int(v.NOutput); i++ { + xgb.Put32(buf[b:], uint32(v.Outputs[i])) + b += 4 + } + + return buf[:b] +} + +// MonitorInfoListBytes writes a list of MonitorInfo values to a byte slice. +func MonitorInfoListBytes(buf []byte, list []MonitorInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// MonitorInfoListSize computes the size (bytes) of a list of MonitorInfo values. +func MonitorInfoListSize(list []MonitorInfo) int { + size := 0 + for _, item := range list { + size += (24 + xgb.Pad((int(item.NOutput) * 4))) + } + return size +} + +const ( + NotifyCrtcChange = 0 + NotifyOutputChange = 1 + NotifyOutputProperty = 2 + NotifyProviderChange = 3 + NotifyProviderProperty = 4 + NotifyResourceChange = 5 + NotifyLease = 6 +) + +// Notify is the event number for a NotifyEvent. +const Notify = 1 + +type NotifyEvent struct { + Sequence uint16 + SubCode byte + U NotifyDataUnion +} + +// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice. +func NotifyEventNew(buf []byte) xgb.Event { + v := NotifyEvent{} + b := 1 // don't read event number + + v.SubCode = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.U = NotifyDataUnion{} + b += NotifyDataUnionRead(buf[b:], &v.U) + + return v +} + +// Bytes writes a NotifyEvent value to a byte slice. +func (v NotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 1 + b += 1 + + buf[b] = v.SubCode + b += 1 + + b += 2 // skip sequence number + + { + unionBytes := v.U.Bytes() + copy(buf[b:], unionBytes) + b += len(unionBytes) + } + + return buf +} + +// SequenceId returns the sequence id attached to the Notify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v NotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of NotifyEvent. +func (v NotifyEvent) String() string { + fieldVals := make([]string, 0, 2) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("SubCode: %d", v.SubCode)) + return "Notify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["RANDR"][1] = NotifyEventNew +} + +// NotifyDataUnion is a represention of the NotifyDataUnion union type. +// Note that to *create* a Union, you should *never* create +// this struct directly (unless you know what you're doing). +// Instead use one of the following constructors for 'NotifyDataUnion': +// +// NotifyDataUnionCcNew(Cc CrtcChange) NotifyDataUnion +// NotifyDataUnionOcNew(Oc OutputChange) NotifyDataUnion +// NotifyDataUnionOpNew(Op OutputProperty) NotifyDataUnion +// NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion +// NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion +// NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion +// NotifyDataUnionLcNew(Lc LeaseNotify) NotifyDataUnion +type NotifyDataUnion struct { + Cc CrtcChange + Oc OutputChange + Op OutputProperty + Pc ProviderChange + Pp ProviderProperty + Rc ResourceChange + Lc LeaseNotify +} + +// NotifyDataUnionCcNew constructs a new NotifyDataUnion union type with the Cc field. +func NotifyDataUnionCcNew(Cc CrtcChange) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Cc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionOcNew constructs a new NotifyDataUnion union type with the Oc field. +func NotifyDataUnionOcNew(Oc OutputChange) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Oc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionOpNew constructs a new NotifyDataUnion union type with the Op field. +func NotifyDataUnionOpNew(Op OutputProperty) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Op.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionPcNew constructs a new NotifyDataUnion union type with the Pc field. +func NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Pc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionPpNew constructs a new NotifyDataUnion union type with the Pp field. +func NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Pp.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionRcNew constructs a new NotifyDataUnion union type with the Rc field. +func NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Rc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionLcNew constructs a new NotifyDataUnion union type with the Lc field. +func NotifyDataUnionLcNew(Lc LeaseNotify) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Lc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionRead reads a byte slice into a NotifyDataUnion value. +func NotifyDataUnionRead(buf []byte, v *NotifyDataUnion) int { + var b int + + b = 0 // re-read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // re-read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // re-read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // re-read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // re-read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // re-read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // re-read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return 28 +} + +// NotifyDataUnionReadList reads a byte slice into a list of NotifyDataUnion values. +func NotifyDataUnionReadList(buf []byte, dest []NotifyDataUnion) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = NotifyDataUnion{} + b += NotifyDataUnionRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a NotifyDataUnion value to a byte slice. +// Each field in a union must contain the same data. +// So simply pick the first field and write that to the wire. +func (v NotifyDataUnion) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + { + structBytes := v.Cc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return buf +} + +// NotifyDataUnionListBytes writes a list of NotifyDataUnion values to a byte slice. +func NotifyDataUnionListBytes(buf []byte, list []NotifyDataUnion) int { + b := 0 + var unionBytes []byte + for _, item := range list { + unionBytes = item.Bytes() + copy(buf[b:], unionBytes) + b += xgb.Pad(len(unionBytes)) + } + return b +} + +const ( + NotifyMaskScreenChange = 1 + NotifyMaskCrtcChange = 2 + NotifyMaskOutputChange = 4 + NotifyMaskOutputProperty = 8 + NotifyMaskProviderChange = 16 + NotifyMaskProviderProperty = 32 + NotifyMaskResourceChange = 64 + NotifyMaskLease = 128 +) + +type Output uint32 + +func NewOutputId(c *xgb.Conn) (Output, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Output(id), nil +} + +type OutputChange struct { + Timestamp xproto.Timestamp + ConfigTimestamp xproto.Timestamp + Window xproto.Window + Output Output + Crtc Crtc + Mode Mode + Rotation uint16 + Connection byte + SubpixelOrder byte +} + +// OutputChangeRead reads a byte slice into a OutputChange value. +func OutputChangeRead(buf []byte, v *OutputChange) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.ConfigTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Output = Output(xgb.Get32(buf[b:])) + b += 4 + + v.Crtc = Crtc(xgb.Get32(buf[b:])) + b += 4 + + v.Mode = Mode(xgb.Get32(buf[b:])) + b += 4 + + v.Rotation = xgb.Get16(buf[b:]) + b += 2 + + v.Connection = buf[b] + b += 1 + + v.SubpixelOrder = buf[b] + b += 1 + + return b +} + +// OutputChangeReadList reads a byte slice into a list of OutputChange values. +func OutputChangeReadList(buf []byte, dest []OutputChange) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = OutputChange{} + b += OutputChangeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a OutputChange value to a byte slice. +func (v OutputChange) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.ConfigTimestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Crtc)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Mode)) + b += 4 + + xgb.Put16(buf[b:], v.Rotation) + b += 2 + + buf[b] = v.Connection + b += 1 + + buf[b] = v.SubpixelOrder + b += 1 + + return buf[:b] +} + +// OutputChangeListBytes writes a list of OutputChange values to a byte slice. +func OutputChangeListBytes(buf []byte, list []OutputChange) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type OutputProperty struct { + Window xproto.Window + Output Output + Atom xproto.Atom + Timestamp xproto.Timestamp + Status byte + // padding: 11 bytes +} + +// OutputPropertyRead reads a byte slice into a OutputProperty value. +func OutputPropertyRead(buf []byte, v *OutputProperty) int { + b := 0 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Output = Output(xgb.Get32(buf[b:])) + b += 4 + + v.Atom = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Status = buf[b] + b += 1 + + b += 11 // padding + + return b +} + +// OutputPropertyReadList reads a byte slice into a list of OutputProperty values. +func OutputPropertyReadList(buf []byte, dest []OutputProperty) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = OutputProperty{} + b += OutputPropertyRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a OutputProperty value to a byte slice. +func (v OutputProperty) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Atom)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + buf[b] = v.Status + b += 1 + + b += 11 // padding + + return buf[:b] +} + +// OutputPropertyListBytes writes a list of OutputProperty values to a byte slice. +func OutputPropertyListBytes(buf []byte, list []OutputProperty) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Provider uint32 + +func NewProviderId(c *xgb.Conn) (Provider, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Provider(id), nil +} + +const ( + ProviderCapabilitySourceOutput = 1 + ProviderCapabilitySinkOutput = 2 + ProviderCapabilitySourceOffload = 4 + ProviderCapabilitySinkOffload = 8 +) + +type ProviderChange struct { + Timestamp xproto.Timestamp + Window xproto.Window + Provider Provider + // padding: 16 bytes +} + +// ProviderChangeRead reads a byte slice into a ProviderChange value. +func ProviderChangeRead(buf []byte, v *ProviderChange) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Provider = Provider(xgb.Get32(buf[b:])) + b += 4 + + b += 16 // padding + + return b +} + +// ProviderChangeReadList reads a byte slice into a list of ProviderChange values. +func ProviderChangeReadList(buf []byte, dest []ProviderChange) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ProviderChange{} + b += ProviderChangeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ProviderChange value to a byte slice. +func (v ProviderChange) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Provider)) + b += 4 + + b += 16 // padding + + return buf[:b] +} + +// ProviderChangeListBytes writes a list of ProviderChange values to a byte slice. +func ProviderChangeListBytes(buf []byte, list []ProviderChange) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type ProviderProperty struct { + Window xproto.Window + Provider Provider + Atom xproto.Atom + Timestamp xproto.Timestamp + State byte + // padding: 11 bytes +} + +// ProviderPropertyRead reads a byte slice into a ProviderProperty value. +func ProviderPropertyRead(buf []byte, v *ProviderProperty) int { + b := 0 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Provider = Provider(xgb.Get32(buf[b:])) + b += 4 + + v.Atom = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.State = buf[b] + b += 1 + + b += 11 // padding + + return b +} + +// ProviderPropertyReadList reads a byte slice into a list of ProviderProperty values. +func ProviderPropertyReadList(buf []byte, dest []ProviderProperty) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ProviderProperty value to a byte slice. +func (v ProviderProperty) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Atom)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + buf[b] = v.State + b += 1 + + b += 11 // padding + + return buf[:b] +} + +// ProviderPropertyListBytes writes a list of ProviderProperty values to a byte slice. +func ProviderPropertyListBytes(buf []byte, list []ProviderProperty) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type RefreshRates struct { + NRates uint16 + Rates []uint16 // size: xgb.Pad((int(NRates) * 2)) +} + +// RefreshRatesRead reads a byte slice into a RefreshRates value. +func RefreshRatesRead(buf []byte, v *RefreshRates) int { + b := 0 + + v.NRates = xgb.Get16(buf[b:]) + b += 2 + + v.Rates = make([]uint16, v.NRates) + for i := 0; i < int(v.NRates); i++ { + v.Rates[i] = xgb.Get16(buf[b:]) + b += 2 + } + + return b +} + +// RefreshRatesReadList reads a byte slice into a list of RefreshRates values. +func RefreshRatesReadList(buf []byte, dest []RefreshRates) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = RefreshRates{} + b += RefreshRatesRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a RefreshRates value to a byte slice. +func (v RefreshRates) Bytes() []byte { + buf := make([]byte, (2 + xgb.Pad((int(v.NRates) * 2)))) + b := 0 + + xgb.Put16(buf[b:], v.NRates) + b += 2 + + for i := 0; i < int(v.NRates); i++ { + xgb.Put16(buf[b:], v.Rates[i]) + b += 2 + } + + return buf[:b] +} + +// RefreshRatesListBytes writes a list of RefreshRates values to a byte slice. +func RefreshRatesListBytes(buf []byte, list []RefreshRates) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// RefreshRatesListSize computes the size (bytes) of a list of RefreshRates values. +func RefreshRatesListSize(list []RefreshRates) int { + size := 0 + for _, item := range list { + size += (2 + xgb.Pad((int(item.NRates) * 2))) + } + return size +} + +type ResourceChange struct { + Timestamp xproto.Timestamp + Window xproto.Window + // padding: 20 bytes +} + +// ResourceChangeRead reads a byte slice into a ResourceChange value. +func ResourceChangeRead(buf []byte, v *ResourceChange) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + return b +} + +// ResourceChangeReadList reads a byte slice into a list of ResourceChange values. +func ResourceChangeReadList(buf []byte, dest []ResourceChange) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ResourceChange{} + b += ResourceChangeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ResourceChange value to a byte slice. +func (v ResourceChange) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + b += 20 // padding + + return buf[:b] +} + +// ResourceChangeListBytes writes a list of ResourceChange values to a byte slice. +func ResourceChangeListBytes(buf []byte, list []ResourceChange) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + RotationRotate0 = 1 + RotationRotate90 = 2 + RotationRotate180 = 4 + RotationRotate270 = 8 + RotationReflectX = 16 + RotationReflectY = 32 +) + +// ScreenChangeNotify is the event number for a ScreenChangeNotifyEvent. +const ScreenChangeNotify = 0 + +type ScreenChangeNotifyEvent struct { + Sequence uint16 + Rotation byte + Timestamp xproto.Timestamp + ConfigTimestamp xproto.Timestamp + Root xproto.Window + RequestWindow xproto.Window + SizeID uint16 + SubpixelOrder uint16 + Width uint16 + Height uint16 + Mwidth uint16 + Mheight uint16 +} + +// ScreenChangeNotifyEventNew constructs a ScreenChangeNotifyEvent value that implements xgb.Event from a byte slice. +func ScreenChangeNotifyEventNew(buf []byte) xgb.Event { + v := ScreenChangeNotifyEvent{} + b := 1 // don't read event number + + v.Rotation = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.ConfigTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.RequestWindow = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.SizeID = xgb.Get16(buf[b:]) + b += 2 + + v.SubpixelOrder = xgb.Get16(buf[b:]) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Mwidth = xgb.Get16(buf[b:]) + b += 2 + + v.Mheight = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Bytes writes a ScreenChangeNotifyEvent value to a byte slice. +func (v ScreenChangeNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = v.Rotation + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.ConfigTimestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.RequestWindow)) + b += 4 + + xgb.Put16(buf[b:], v.SizeID) + b += 2 + + xgb.Put16(buf[b:], v.SubpixelOrder) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.Mwidth) + b += 2 + + xgb.Put16(buf[b:], v.Mheight) + b += 2 + + return buf +} + +// SequenceId returns the sequence id attached to the ScreenChangeNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ScreenChangeNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ScreenChangeNotifyEvent. +func (v ScreenChangeNotifyEvent) String() string { + fieldVals := make([]string, 0, 11) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Rotation: %d", v.Rotation)) + fieldVals = append(fieldVals, xgb.Sprintf("Timestamp: %d", v.Timestamp)) + fieldVals = append(fieldVals, xgb.Sprintf("ConfigTimestamp: %d", v.ConfigTimestamp)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("RequestWindow: %d", v.RequestWindow)) + fieldVals = append(fieldVals, xgb.Sprintf("SizeID: %d", v.SizeID)) + fieldVals = append(fieldVals, xgb.Sprintf("SubpixelOrder: %d", v.SubpixelOrder)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("Mwidth: %d", v.Mwidth)) + fieldVals = append(fieldVals, xgb.Sprintf("Mheight: %d", v.Mheight)) + return "ScreenChangeNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["RANDR"][0] = ScreenChangeNotifyEventNew +} + +type ScreenSize struct { + Width uint16 + Height uint16 + Mwidth uint16 + Mheight uint16 +} + +// ScreenSizeRead reads a byte slice into a ScreenSize value. +func ScreenSizeRead(buf []byte, v *ScreenSize) int { + b := 0 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Mwidth = xgb.Get16(buf[b:]) + b += 2 + + v.Mheight = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// ScreenSizeReadList reads a byte slice into a list of ScreenSize values. +func ScreenSizeReadList(buf []byte, dest []ScreenSize) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ScreenSize{} + b += ScreenSizeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ScreenSize value to a byte slice. +func (v ScreenSize) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.Mwidth) + b += 2 + + xgb.Put16(buf[b:], v.Mheight) + b += 2 + + return buf[:b] +} + +// ScreenSizeListBytes writes a list of ScreenSize values to a byte slice. +func ScreenSizeListBytes(buf []byte, list []ScreenSize) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + SetConfigSuccess = 0 + SetConfigInvalidConfigTime = 1 + SetConfigInvalidTime = 2 + SetConfigFailed = 3 +) + +const ( + TransformUnit = 1 + TransformScaleUp = 2 + TransformScaleDown = 4 + TransformProjective = 8 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AddOutputModeCookie is a cookie used only for AddOutputMode requests. +type AddOutputModeCookie struct { + *xgb.Cookie +} + +// AddOutputMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AddOutputMode(c *xgb.Conn, Output Output, Mode Mode) AddOutputModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'AddOutputMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(addOutputModeRequest(c, Output, Mode), cookie) + return AddOutputModeCookie{cookie} +} + +// AddOutputModeChecked sends a checked request. +// If an error occurs, it can be retrieved using AddOutputModeCookie.Check() +func AddOutputModeChecked(c *xgb.Conn, Output Output, Mode Mode) AddOutputModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'AddOutputMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(addOutputModeRequest(c, Output, Mode), cookie) + return AddOutputModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AddOutputModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for AddOutputMode +// addOutputModeRequest writes a AddOutputMode request to a byte slice. +func addOutputModeRequest(c *xgb.Conn, Output Output, Mode Mode) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Mode)) + b += 4 + + return buf +} + +// ChangeOutputPropertyCookie is a cookie used only for ChangeOutputProperty requests. +type ChangeOutputPropertyCookie struct { + *xgb.Cookie +} + +// ChangeOutputProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeOutputProperty(c *xgb.Conn, Output Output, Property xproto.Atom, Type xproto.Atom, Format byte, Mode byte, NumUnits uint32, Data []byte) ChangeOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ChangeOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changeOutputPropertyRequest(c, Output, Property, Type, Format, Mode, NumUnits, Data), cookie) + return ChangeOutputPropertyCookie{cookie} +} + +// ChangeOutputPropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeOutputPropertyCookie.Check() +func ChangeOutputPropertyChecked(c *xgb.Conn, Output Output, Property xproto.Atom, Type xproto.Atom, Format byte, Mode byte, NumUnits uint32, Data []byte) ChangeOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ChangeOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changeOutputPropertyRequest(c, Output, Property, Type, Format, Mode, NumUnits, Data), cookie) + return ChangeOutputPropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeOutputPropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeOutputProperty +// changeOutputPropertyRequest writes a ChangeOutputProperty request to a byte slice. +func changeOutputPropertyRequest(c *xgb.Conn, Output Output, Property xproto.Atom, Type xproto.Atom, Format byte, Mode byte, NumUnits uint32, Data []byte) []byte { + size := xgb.Pad((24 + xgb.Pad((((int(NumUnits) * int(Format)) / 8) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + buf[b] = Format + b += 1 + + buf[b] = Mode + b += 1 + + b += 2 // padding + + xgb.Put32(buf[b:], NumUnits) + b += 4 + + copy(buf[b:], Data[:((int(NumUnits)*int(Format))/8)]) + b += int(((int(NumUnits) * int(Format)) / 8)) + + return buf +} + +// ChangeProviderPropertyCookie is a cookie used only for ChangeProviderProperty requests. +type ChangeProviderPropertyCookie struct { + *xgb.Cookie +} + +// ChangeProviderProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeProviderProperty(c *xgb.Conn, Provider Provider, Property xproto.Atom, Type xproto.Atom, Format byte, Mode byte, NumItems uint32, Data []byte) ChangeProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ChangeProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changeProviderPropertyRequest(c, Provider, Property, Type, Format, Mode, NumItems, Data), cookie) + return ChangeProviderPropertyCookie{cookie} +} + +// ChangeProviderPropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeProviderPropertyCookie.Check() +func ChangeProviderPropertyChecked(c *xgb.Conn, Provider Provider, Property xproto.Atom, Type xproto.Atom, Format byte, Mode byte, NumItems uint32, Data []byte) ChangeProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ChangeProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changeProviderPropertyRequest(c, Provider, Property, Type, Format, Mode, NumItems, Data), cookie) + return ChangeProviderPropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeProviderPropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeProviderProperty +// changeProviderPropertyRequest writes a ChangeProviderProperty request to a byte slice. +func changeProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property xproto.Atom, Type xproto.Atom, Format byte, Mode byte, NumItems uint32, Data []byte) []byte { + size := xgb.Pad((24 + xgb.Pad(((int(NumItems) * (int(Format) / 8)) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 39 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + buf[b] = Format + b += 1 + + buf[b] = Mode + b += 1 + + b += 2 // padding + + xgb.Put32(buf[b:], NumItems) + b += 4 + + copy(buf[b:], Data[:(int(NumItems)*(int(Format)/8))]) + b += int((int(NumItems) * (int(Format) / 8))) + + return buf +} + +// ConfigureOutputPropertyCookie is a cookie used only for ConfigureOutputProperty requests. +type ConfigureOutputPropertyCookie struct { + *xgb.Cookie +} + +// ConfigureOutputProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ConfigureOutputProperty(c *xgb.Conn, Output Output, Property xproto.Atom, Pending bool, Range bool, Values []int32) ConfigureOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ConfigureOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(configureOutputPropertyRequest(c, Output, Property, Pending, Range, Values), cookie) + return ConfigureOutputPropertyCookie{cookie} +} + +// ConfigureOutputPropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using ConfigureOutputPropertyCookie.Check() +func ConfigureOutputPropertyChecked(c *xgb.Conn, Output Output, Property xproto.Atom, Pending bool, Range bool, Values []int32) ConfigureOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ConfigureOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(configureOutputPropertyRequest(c, Output, Property, Pending, Range, Values), cookie) + return ConfigureOutputPropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ConfigureOutputPropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ConfigureOutputProperty +// configureOutputPropertyRequest writes a ConfigureOutputProperty request to a byte slice. +func configureOutputPropertyRequest(c *xgb.Conn, Output Output, Property xproto.Atom, Pending bool, Range bool, Values []int32) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Values) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + if Pending { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if Range { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 2 // padding + + for i := 0; i < int(len(Values)); i++ { + xgb.Put32(buf[b:], uint32(Values[i])) + b += 4 + } + + return buf +} + +// ConfigureProviderPropertyCookie is a cookie used only for ConfigureProviderProperty requests. +type ConfigureProviderPropertyCookie struct { + *xgb.Cookie +} + +// ConfigureProviderProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ConfigureProviderProperty(c *xgb.Conn, Provider Provider, Property xproto.Atom, Pending bool, Range bool, Values []int32) ConfigureProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ConfigureProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(configureProviderPropertyRequest(c, Provider, Property, Pending, Range, Values), cookie) + return ConfigureProviderPropertyCookie{cookie} +} + +// ConfigureProviderPropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using ConfigureProviderPropertyCookie.Check() +func ConfigureProviderPropertyChecked(c *xgb.Conn, Provider Provider, Property xproto.Atom, Pending bool, Range bool, Values []int32) ConfigureProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ConfigureProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(configureProviderPropertyRequest(c, Provider, Property, Pending, Range, Values), cookie) + return ConfigureProviderPropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ConfigureProviderPropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ConfigureProviderProperty +// configureProviderPropertyRequest writes a ConfigureProviderProperty request to a byte slice. +func configureProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property xproto.Atom, Pending bool, Range bool, Values []int32) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Values) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 38 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + if Pending { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if Range { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 2 // padding + + for i := 0; i < int(len(Values)); i++ { + xgb.Put32(buf[b:], uint32(Values[i])) + b += 4 + } + + return buf +} + +// CreateLeaseCookie is a cookie used only for CreateLease requests. +type CreateLeaseCookie struct { + *xgb.Cookie +} + +// CreateLease sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateLeaseCookie.Reply() +func CreateLease(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs uint16, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) CreateLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createLeaseRequest(c, Window, Lid, NumCrtcs, NumOutputs, Crtcs, Outputs), cookie) + return CreateLeaseCookie{cookie} +} + +// CreateLeaseUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateLeaseUnchecked(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs uint16, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) CreateLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createLeaseRequest(c, Window, Lid, NumCrtcs, NumOutputs, Crtcs, Outputs), cookie) + return CreateLeaseCookie{cookie} +} + +// CreateLeaseReply represents the data returned from a CreateLease request. +type CreateLeaseReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Nfd byte + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a CreateLease request. +func (cook CreateLeaseCookie) Reply() (*CreateLeaseReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createLeaseReply(buf), nil +} + +// createLeaseReply reads a byte slice into a CreateLeaseReply value. +func createLeaseReply(buf []byte) *CreateLeaseReply { + v := new(CreateLeaseReply) + b := 1 // skip reply determinant + + v.Nfd = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for CreateLease +// createLeaseRequest writes a CreateLease request to a byte slice. +func createLeaseRequest(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs uint16, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) []byte { + size := xgb.Pad(((16 + xgb.Pad((int(NumCrtcs) * 4))) + xgb.Pad((int(NumOutputs) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 45 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Lid)) + b += 4 + + xgb.Put16(buf[b:], NumCrtcs) + b += 2 + + xgb.Put16(buf[b:], NumOutputs) + b += 2 + + for i := 0; i < int(NumCrtcs); i++ { + xgb.Put32(buf[b:], uint32(Crtcs[i])) + b += 4 + } + + for i := 0; i < int(NumOutputs); i++ { + xgb.Put32(buf[b:], uint32(Outputs[i])) + b += 4 + } + + return buf +} + +// CreateModeCookie is a cookie used only for CreateMode requests. +type CreateModeCookie struct { + *xgb.Cookie +} + +// CreateMode sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateModeCookie.Reply() +func CreateMode(c *xgb.Conn, Window xproto.Window, ModeInfo ModeInfo, Name string) CreateModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createModeRequest(c, Window, ModeInfo, Name), cookie) + return CreateModeCookie{cookie} +} + +// CreateModeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateModeUnchecked(c *xgb.Conn, Window xproto.Window, ModeInfo ModeInfo, Name string) CreateModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createModeRequest(c, Window, ModeInfo, Name), cookie) + return CreateModeCookie{cookie} +} + +// CreateModeReply represents the data returned from a CreateMode request. +type CreateModeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Mode Mode + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a CreateMode request. +func (cook CreateModeCookie) Reply() (*CreateModeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createModeReply(buf), nil +} + +// createModeReply reads a byte slice into a CreateModeReply value. +func createModeReply(buf []byte) *CreateModeReply { + v := new(CreateModeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Mode = Mode(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for CreateMode +// createModeRequest writes a CreateMode request to a byte slice. +func createModeRequest(c *xgb.Conn, Window xproto.Window, ModeInfo ModeInfo, Name string) []byte { + size := xgb.Pad((40 + xgb.Pad((len(Name) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + { + structBytes := ModeInfo.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + copy(buf[b:], Name[:len(Name)]) + b += int(len(Name)) + + return buf +} + +// DeleteMonitorCookie is a cookie used only for DeleteMonitor requests. +type DeleteMonitorCookie struct { + *xgb.Cookie +} + +// DeleteMonitor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteMonitor(c *xgb.Conn, Window xproto.Window, Name xproto.Atom) DeleteMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteMonitorRequest(c, Window, Name), cookie) + return DeleteMonitorCookie{cookie} +} + +// DeleteMonitorChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteMonitorCookie.Check() +func DeleteMonitorChecked(c *xgb.Conn, Window xproto.Window, Name xproto.Atom) DeleteMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteMonitorRequest(c, Window, Name), cookie) + return DeleteMonitorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteMonitorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteMonitor +// deleteMonitorRequest writes a DeleteMonitor request to a byte slice. +func deleteMonitorRequest(c *xgb.Conn, Window xproto.Window, Name xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 44 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Name)) + b += 4 + + return buf +} + +// DeleteOutputModeCookie is a cookie used only for DeleteOutputMode requests. +type DeleteOutputModeCookie struct { + *xgb.Cookie +} + +// DeleteOutputMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteOutputMode(c *xgb.Conn, Output Output, Mode Mode) DeleteOutputModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteOutputMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteOutputModeRequest(c, Output, Mode), cookie) + return DeleteOutputModeCookie{cookie} +} + +// DeleteOutputModeChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteOutputModeCookie.Check() +func DeleteOutputModeChecked(c *xgb.Conn, Output Output, Mode Mode) DeleteOutputModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteOutputMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteOutputModeRequest(c, Output, Mode), cookie) + return DeleteOutputModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteOutputModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteOutputMode +// deleteOutputModeRequest writes a DeleteOutputMode request to a byte slice. +func deleteOutputModeRequest(c *xgb.Conn, Output Output, Mode Mode) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Mode)) + b += 4 + + return buf +} + +// DeleteOutputPropertyCookie is a cookie used only for DeleteOutputProperty requests. +type DeleteOutputPropertyCookie struct { + *xgb.Cookie +} + +// DeleteOutputProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteOutputProperty(c *xgb.Conn, Output Output, Property xproto.Atom) DeleteOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteOutputPropertyRequest(c, Output, Property), cookie) + return DeleteOutputPropertyCookie{cookie} +} + +// DeleteOutputPropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteOutputPropertyCookie.Check() +func DeleteOutputPropertyChecked(c *xgb.Conn, Output Output, Property xproto.Atom) DeleteOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteOutputPropertyRequest(c, Output, Property), cookie) + return DeleteOutputPropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteOutputPropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteOutputProperty +// deleteOutputPropertyRequest writes a DeleteOutputProperty request to a byte slice. +func deleteOutputPropertyRequest(c *xgb.Conn, Output Output, Property xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// DeleteProviderPropertyCookie is a cookie used only for DeleteProviderProperty requests. +type DeleteProviderPropertyCookie struct { + *xgb.Cookie +} + +// DeleteProviderProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteProviderProperty(c *xgb.Conn, Provider Provider, Property xproto.Atom) DeleteProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteProviderPropertyRequest(c, Provider, Property), cookie) + return DeleteProviderPropertyCookie{cookie} +} + +// DeleteProviderPropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteProviderPropertyCookie.Check() +func DeleteProviderPropertyChecked(c *xgb.Conn, Provider Provider, Property xproto.Atom) DeleteProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteProviderPropertyRequest(c, Provider, Property), cookie) + return DeleteProviderPropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteProviderPropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteProviderProperty +// deleteProviderPropertyRequest writes a DeleteProviderProperty request to a byte slice. +func deleteProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 40 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// DestroyModeCookie is a cookie used only for DestroyMode requests. +type DestroyModeCookie struct { + *xgb.Cookie +} + +// DestroyMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyMode(c *xgb.Conn, Mode Mode) DestroyModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DestroyMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyModeRequest(c, Mode), cookie) + return DestroyModeCookie{cookie} +} + +// DestroyModeChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyModeCookie.Check() +func DestroyModeChecked(c *xgb.Conn, Mode Mode) DestroyModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DestroyMode' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyModeRequest(c, Mode), cookie) + return DestroyModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyMode +// destroyModeRequest writes a DestroyMode request to a byte slice. +func destroyModeRequest(c *xgb.Conn, Mode Mode) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Mode)) + b += 4 + + return buf +} + +// FreeLeaseCookie is a cookie used only for FreeLease requests. +type FreeLeaseCookie struct { + *xgb.Cookie +} + +// FreeLease sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeLease(c *xgb.Conn, Lid Lease, Terminate byte) FreeLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'FreeLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freeLeaseRequest(c, Lid, Terminate), cookie) + return FreeLeaseCookie{cookie} +} + +// FreeLeaseChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeLeaseCookie.Check() +func FreeLeaseChecked(c *xgb.Conn, Lid Lease, Terminate byte) FreeLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'FreeLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freeLeaseRequest(c, Lid, Terminate), cookie) + return FreeLeaseCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeLeaseCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeLease +// freeLeaseRequest writes a FreeLease request to a byte slice. +func freeLeaseRequest(c *xgb.Conn, Lid Lease, Terminate byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 46 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Lid)) + b += 4 + + buf[b] = Terminate + b += 1 + + return buf +} + +// GetCrtcGammaCookie is a cookie used only for GetCrtcGamma requests. +type GetCrtcGammaCookie struct { + *xgb.Cookie +} + +// GetCrtcGamma sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCrtcGammaCookie.Reply() +func GetCrtcGamma(c *xgb.Conn, Crtc Crtc) GetCrtcGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcGamma' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCrtcGammaRequest(c, Crtc), cookie) + return GetCrtcGammaCookie{cookie} +} + +// GetCrtcGammaUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCrtcGammaUnchecked(c *xgb.Conn, Crtc Crtc) GetCrtcGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcGamma' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCrtcGammaRequest(c, Crtc), cookie) + return GetCrtcGammaCookie{cookie} +} + +// GetCrtcGammaReply represents the data returned from a GetCrtcGamma request. +type GetCrtcGammaReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Size uint16 + // padding: 22 bytes + Red []uint16 // size: xgb.Pad((int(Size) * 2)) + Green []uint16 // size: xgb.Pad((int(Size) * 2)) + Blue []uint16 // size: xgb.Pad((int(Size) * 2)) +} + +// Reply blocks and returns the reply data for a GetCrtcGamma request. +func (cook GetCrtcGammaCookie) Reply() (*GetCrtcGammaReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCrtcGammaReply(buf), nil +} + +// getCrtcGammaReply reads a byte slice into a GetCrtcGammaReply value. +func getCrtcGammaReply(buf []byte) *GetCrtcGammaReply { + v := new(GetCrtcGammaReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Size = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Red = make([]uint16, v.Size) + for i := 0; i < int(v.Size); i++ { + v.Red[i] = xgb.Get16(buf[b:]) + b += 2 + } + + v.Green = make([]uint16, v.Size) + for i := 0; i < int(v.Size); i++ { + v.Green[i] = xgb.Get16(buf[b:]) + b += 2 + } + + v.Blue = make([]uint16, v.Size) + for i := 0; i < int(v.Size); i++ { + v.Blue[i] = xgb.Get16(buf[b:]) + b += 2 + } + + return v +} + +// Write request to wire for GetCrtcGamma +// getCrtcGammaRequest writes a GetCrtcGamma request to a byte slice. +func getCrtcGammaRequest(c *xgb.Conn, Crtc Crtc) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 23 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + return buf +} + +// GetCrtcGammaSizeCookie is a cookie used only for GetCrtcGammaSize requests. +type GetCrtcGammaSizeCookie struct { + *xgb.Cookie +} + +// GetCrtcGammaSize sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCrtcGammaSizeCookie.Reply() +func GetCrtcGammaSize(c *xgb.Conn, Crtc Crtc) GetCrtcGammaSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcGammaSize' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCrtcGammaSizeRequest(c, Crtc), cookie) + return GetCrtcGammaSizeCookie{cookie} +} + +// GetCrtcGammaSizeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCrtcGammaSizeUnchecked(c *xgb.Conn, Crtc Crtc) GetCrtcGammaSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcGammaSize' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCrtcGammaSizeRequest(c, Crtc), cookie) + return GetCrtcGammaSizeCookie{cookie} +} + +// GetCrtcGammaSizeReply represents the data returned from a GetCrtcGammaSize request. +type GetCrtcGammaSizeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Size uint16 + // padding: 22 bytes +} + +// Reply blocks and returns the reply data for a GetCrtcGammaSize request. +func (cook GetCrtcGammaSizeCookie) Reply() (*GetCrtcGammaSizeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCrtcGammaSizeReply(buf), nil +} + +// getCrtcGammaSizeReply reads a byte slice into a GetCrtcGammaSizeReply value. +func getCrtcGammaSizeReply(buf []byte) *GetCrtcGammaSizeReply { + v := new(GetCrtcGammaSizeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Size = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + return v +} + +// Write request to wire for GetCrtcGammaSize +// getCrtcGammaSizeRequest writes a GetCrtcGammaSize request to a byte slice. +func getCrtcGammaSizeRequest(c *xgb.Conn, Crtc Crtc) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 22 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + return buf +} + +// GetCrtcInfoCookie is a cookie used only for GetCrtcInfo requests. +type GetCrtcInfoCookie struct { + *xgb.Cookie +} + +// GetCrtcInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCrtcInfoCookie.Reply() +func GetCrtcInfo(c *xgb.Conn, Crtc Crtc, ConfigTimestamp xproto.Timestamp) GetCrtcInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCrtcInfoRequest(c, Crtc, ConfigTimestamp), cookie) + return GetCrtcInfoCookie{cookie} +} + +// GetCrtcInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCrtcInfoUnchecked(c *xgb.Conn, Crtc Crtc, ConfigTimestamp xproto.Timestamp) GetCrtcInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCrtcInfoRequest(c, Crtc, ConfigTimestamp), cookie) + return GetCrtcInfoCookie{cookie} +} + +// GetCrtcInfoReply represents the data returned from a GetCrtcInfo request. +type GetCrtcInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + Timestamp xproto.Timestamp + X int16 + Y int16 + Width uint16 + Height uint16 + Mode Mode + Rotation uint16 + Rotations uint16 + NumOutputs uint16 + NumPossibleOutputs uint16 + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + Possible []Output // size: xgb.Pad((int(NumPossibleOutputs) * 4)) +} + +// Reply blocks and returns the reply data for a GetCrtcInfo request. +func (cook GetCrtcInfoCookie) Reply() (*GetCrtcInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCrtcInfoReply(buf), nil +} + +// getCrtcInfoReply reads a byte slice into a GetCrtcInfoReply value. +func getCrtcInfoReply(buf []byte) *GetCrtcInfoReply { + v := new(GetCrtcInfoReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Mode = Mode(xgb.Get32(buf[b:])) + b += 4 + + v.Rotation = xgb.Get16(buf[b:]) + b += 2 + + v.Rotations = xgb.Get16(buf[b:]) + b += 2 + + v.NumOutputs = xgb.Get16(buf[b:]) + b += 2 + + v.NumPossibleOutputs = xgb.Get16(buf[b:]) + b += 2 + + v.Outputs = make([]Output, v.NumOutputs) + for i := 0; i < int(v.NumOutputs); i++ { + v.Outputs[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + v.Possible = make([]Output, v.NumPossibleOutputs) + for i := 0; i < int(v.NumPossibleOutputs); i++ { + v.Possible[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetCrtcInfo +// getCrtcInfoRequest writes a GetCrtcInfo request to a byte slice. +func getCrtcInfoRequest(c *xgb.Conn, Crtc Crtc, ConfigTimestamp xproto.Timestamp) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + return buf +} + +// GetCrtcTransformCookie is a cookie used only for GetCrtcTransform requests. +type GetCrtcTransformCookie struct { + *xgb.Cookie +} + +// GetCrtcTransform sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCrtcTransformCookie.Reply() +func GetCrtcTransform(c *xgb.Conn, Crtc Crtc) GetCrtcTransformCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcTransform' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCrtcTransformRequest(c, Crtc), cookie) + return GetCrtcTransformCookie{cookie} +} + +// GetCrtcTransformUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCrtcTransformUnchecked(c *xgb.Conn, Crtc Crtc) GetCrtcTransformCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetCrtcTransform' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCrtcTransformRequest(c, Crtc), cookie) + return GetCrtcTransformCookie{cookie} +} + +// GetCrtcTransformReply represents the data returned from a GetCrtcTransform request. +type GetCrtcTransformReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + PendingTransform render.Transform + HasTransforms bool + // padding: 3 bytes + CurrentTransform render.Transform + // padding: 4 bytes + PendingLen uint16 + PendingNparams uint16 + CurrentLen uint16 + CurrentNparams uint16 + PendingFilterName string // size: xgb.Pad((int(PendingLen) * 1)) + // alignment gap to multiple of 4 + PendingParams []render.Fixed // size: xgb.Pad((int(PendingNparams) * 4)) + CurrentFilterName string // size: xgb.Pad((int(CurrentLen) * 1)) + // alignment gap to multiple of 4 + CurrentParams []render.Fixed // size: xgb.Pad((int(CurrentNparams) * 4)) +} + +// Reply blocks and returns the reply data for a GetCrtcTransform request. +func (cook GetCrtcTransformCookie) Reply() (*GetCrtcTransformReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCrtcTransformReply(buf), nil +} + +// getCrtcTransformReply reads a byte slice into a GetCrtcTransformReply value. +func getCrtcTransformReply(buf []byte) *GetCrtcTransformReply { + v := new(GetCrtcTransformReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PendingTransform = render.Transform{} + b += render.TransformRead(buf[b:], &v.PendingTransform) + + if buf[b] == 1 { + v.HasTransforms = true + } else { + v.HasTransforms = false + } + b += 1 + + b += 3 // padding + + v.CurrentTransform = render.Transform{} + b += render.TransformRead(buf[b:], &v.CurrentTransform) + + b += 4 // padding + + v.PendingLen = xgb.Get16(buf[b:]) + b += 2 + + v.PendingNparams = xgb.Get16(buf[b:]) + b += 2 + + v.CurrentLen = xgb.Get16(buf[b:]) + b += 2 + + v.CurrentNparams = xgb.Get16(buf[b:]) + b += 2 + + { + byteString := make([]byte, v.PendingLen) + copy(byteString[:v.PendingLen], buf[b:]) + v.PendingFilterName = string(byteString) + b += int(v.PendingLen) + } + + b = (b + 3) & ^3 // alignment gap + + v.PendingParams = make([]render.Fixed, v.PendingNparams) + for i := 0; i < int(v.PendingNparams); i++ { + v.PendingParams[i] = render.Fixed(xgb.Get32(buf[b:])) + b += 4 + } + + { + byteString := make([]byte, v.CurrentLen) + copy(byteString[:v.CurrentLen], buf[b:]) + v.CurrentFilterName = string(byteString) + b += int(v.CurrentLen) + } + + b = (b + 3) & ^3 // alignment gap + + v.CurrentParams = make([]render.Fixed, v.CurrentNparams) + for i := 0; i < int(v.CurrentNparams); i++ { + v.CurrentParams[i] = render.Fixed(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetCrtcTransform +// getCrtcTransformRequest writes a GetCrtcTransform request to a byte slice. +func getCrtcTransformRequest(c *xgb.Conn, Crtc Crtc) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 27 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + return buf +} + +// GetMonitorsCookie is a cookie used only for GetMonitors requests. +type GetMonitorsCookie struct { + *xgb.Cookie +} + +// GetMonitors sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMonitorsCookie.Reply() +func GetMonitors(c *xgb.Conn, Window xproto.Window, GetActive bool) GetMonitorsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetMonitors' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMonitorsRequest(c, Window, GetActive), cookie) + return GetMonitorsCookie{cookie} +} + +// GetMonitorsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMonitorsUnchecked(c *xgb.Conn, Window xproto.Window, GetActive bool) GetMonitorsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetMonitors' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMonitorsRequest(c, Window, GetActive), cookie) + return GetMonitorsCookie{cookie} +} + +// GetMonitorsReply represents the data returned from a GetMonitors request. +type GetMonitorsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Timestamp xproto.Timestamp + NMonitors uint32 + NOutputs uint32 + // padding: 12 bytes + Monitors []MonitorInfo // size: MonitorInfoListSize(Monitors) +} + +// Reply blocks and returns the reply data for a GetMonitors request. +func (cook GetMonitorsCookie) Reply() (*GetMonitorsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMonitorsReply(buf), nil +} + +// getMonitorsReply reads a byte slice into a GetMonitorsReply value. +func getMonitorsReply(buf []byte) *GetMonitorsReply { + v := new(GetMonitorsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.NMonitors = xgb.Get32(buf[b:]) + b += 4 + + v.NOutputs = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Monitors = make([]MonitorInfo, v.NMonitors) + b += MonitorInfoReadList(buf[b:], v.Monitors) + + return v +} + +// Write request to wire for GetMonitors +// getMonitorsRequest writes a GetMonitors request to a byte slice. +func getMonitorsRequest(c *xgb.Conn, Window xproto.Window, GetActive bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 42 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + if GetActive { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// GetOutputInfoCookie is a cookie used only for GetOutputInfo requests. +type GetOutputInfoCookie struct { + *xgb.Cookie +} + +// GetOutputInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetOutputInfoCookie.Reply() +func GetOutputInfo(c *xgb.Conn, Output Output, ConfigTimestamp xproto.Timestamp) GetOutputInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetOutputInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getOutputInfoRequest(c, Output, ConfigTimestamp), cookie) + return GetOutputInfoCookie{cookie} +} + +// GetOutputInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetOutputInfoUnchecked(c *xgb.Conn, Output Output, ConfigTimestamp xproto.Timestamp) GetOutputInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetOutputInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getOutputInfoRequest(c, Output, ConfigTimestamp), cookie) + return GetOutputInfoCookie{cookie} +} + +// GetOutputInfoReply represents the data returned from a GetOutputInfo request. +type GetOutputInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + Timestamp xproto.Timestamp + Crtc Crtc + MmWidth uint32 + MmHeight uint32 + Connection byte + SubpixelOrder byte + NumCrtcs uint16 + NumModes uint16 + NumPreferred uint16 + NumClones uint16 + NameLen uint16 + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Modes []Mode // size: xgb.Pad((int(NumModes) * 4)) + Clones []Output // size: xgb.Pad((int(NumClones) * 4)) + Name []byte // size: xgb.Pad((int(NameLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetOutputInfo request. +func (cook GetOutputInfoCookie) Reply() (*GetOutputInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getOutputInfoReply(buf), nil +} + +// getOutputInfoReply reads a byte slice into a GetOutputInfoReply value. +func getOutputInfoReply(buf []byte) *GetOutputInfoReply { + v := new(GetOutputInfoReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Crtc = Crtc(xgb.Get32(buf[b:])) + b += 4 + + v.MmWidth = xgb.Get32(buf[b:]) + b += 4 + + v.MmHeight = xgb.Get32(buf[b:]) + b += 4 + + v.Connection = buf[b] + b += 1 + + v.SubpixelOrder = buf[b] + b += 1 + + v.NumCrtcs = xgb.Get16(buf[b:]) + b += 2 + + v.NumModes = xgb.Get16(buf[b:]) + b += 2 + + v.NumPreferred = xgb.Get16(buf[b:]) + b += 2 + + v.NumClones = xgb.Get16(buf[b:]) + b += 2 + + v.NameLen = xgb.Get16(buf[b:]) + b += 2 + + v.Crtcs = make([]Crtc, v.NumCrtcs) + for i := 0; i < int(v.NumCrtcs); i++ { + v.Crtcs[i] = Crtc(xgb.Get32(buf[b:])) + b += 4 + } + + v.Modes = make([]Mode, v.NumModes) + for i := 0; i < int(v.NumModes); i++ { + v.Modes[i] = Mode(xgb.Get32(buf[b:])) + b += 4 + } + + v.Clones = make([]Output, v.NumClones) + for i := 0; i < int(v.NumClones); i++ { + v.Clones[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + v.Name = make([]byte, v.NameLen) + copy(v.Name[:v.NameLen], buf[b:]) + b += int(v.NameLen) + + return v +} + +// Write request to wire for GetOutputInfo +// getOutputInfoRequest writes a GetOutputInfo request to a byte slice. +func getOutputInfoRequest(c *xgb.Conn, Output Output, ConfigTimestamp xproto.Timestamp) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + return buf +} + +// GetOutputPrimaryCookie is a cookie used only for GetOutputPrimary requests. +type GetOutputPrimaryCookie struct { + *xgb.Cookie +} + +// GetOutputPrimary sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetOutputPrimaryCookie.Reply() +func GetOutputPrimary(c *xgb.Conn, Window xproto.Window) GetOutputPrimaryCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetOutputPrimary' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getOutputPrimaryRequest(c, Window), cookie) + return GetOutputPrimaryCookie{cookie} +} + +// GetOutputPrimaryUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetOutputPrimaryUnchecked(c *xgb.Conn, Window xproto.Window) GetOutputPrimaryCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetOutputPrimary' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getOutputPrimaryRequest(c, Window), cookie) + return GetOutputPrimaryCookie{cookie} +} + +// GetOutputPrimaryReply represents the data returned from a GetOutputPrimary request. +type GetOutputPrimaryReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Output Output +} + +// Reply blocks and returns the reply data for a GetOutputPrimary request. +func (cook GetOutputPrimaryCookie) Reply() (*GetOutputPrimaryReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getOutputPrimaryReply(buf), nil +} + +// getOutputPrimaryReply reads a byte slice into a GetOutputPrimaryReply value. +func getOutputPrimaryReply(buf []byte) *GetOutputPrimaryReply { + v := new(GetOutputPrimaryReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Output = Output(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetOutputPrimary +// getOutputPrimaryRequest writes a GetOutputPrimary request to a byte slice. +func getOutputPrimaryRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 31 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetOutputPropertyCookie is a cookie used only for GetOutputProperty requests. +type GetOutputPropertyCookie struct { + *xgb.Cookie +} + +// GetOutputProperty sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetOutputPropertyCookie.Reply() +func GetOutputProperty(c *xgb.Conn, Output Output, Property xproto.Atom, Type xproto.Atom, LongOffset uint32, LongLength uint32, Delete bool, Pending bool) GetOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getOutputPropertyRequest(c, Output, Property, Type, LongOffset, LongLength, Delete, Pending), cookie) + return GetOutputPropertyCookie{cookie} +} + +// GetOutputPropertyUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetOutputPropertyUnchecked(c *xgb.Conn, Output Output, Property xproto.Atom, Type xproto.Atom, LongOffset uint32, LongLength uint32, Delete bool, Pending bool) GetOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getOutputPropertyRequest(c, Output, Property, Type, LongOffset, LongLength, Delete, Pending), cookie) + return GetOutputPropertyCookie{cookie} +} + +// GetOutputPropertyReply represents the data returned from a GetOutputProperty request. +type GetOutputPropertyReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Format byte + Type xproto.Atom + BytesAfter uint32 + NumItems uint32 + // padding: 12 bytes + Data []byte // size: xgb.Pad(((int(NumItems) * (int(Format) / 8)) * 1)) +} + +// Reply blocks and returns the reply data for a GetOutputProperty request. +func (cook GetOutputPropertyCookie) Reply() (*GetOutputPropertyReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getOutputPropertyReply(buf), nil +} + +// getOutputPropertyReply reads a byte slice into a GetOutputPropertyReply value. +func getOutputPropertyReply(buf []byte) *GetOutputPropertyReply { + v := new(GetOutputPropertyReply) + b := 1 // skip reply determinant + + v.Format = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Type = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.BytesAfter = xgb.Get32(buf[b:]) + b += 4 + + v.NumItems = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Data = make([]byte, (int(v.NumItems) * (int(v.Format) / 8))) + copy(v.Data[:(int(v.NumItems)*(int(v.Format)/8))], buf[b:]) + b += int((int(v.NumItems) * (int(v.Format) / 8))) + + return v +} + +// Write request to wire for GetOutputProperty +// getOutputPropertyRequest writes a GetOutputProperty request to a byte slice. +func getOutputPropertyRequest(c *xgb.Conn, Output Output, Property xproto.Atom, Type xproto.Atom, LongOffset uint32, LongLength uint32, Delete bool, Pending bool) []byte { + size := 28 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + xgb.Put32(buf[b:], LongOffset) + b += 4 + + xgb.Put32(buf[b:], LongLength) + b += 4 + + if Delete { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if Pending { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 2 // padding + + return buf +} + +// GetPanningCookie is a cookie used only for GetPanning requests. +type GetPanningCookie struct { + *xgb.Cookie +} + +// GetPanning sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPanningCookie.Reply() +func GetPanning(c *xgb.Conn, Crtc Crtc) GetPanningCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetPanning' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPanningRequest(c, Crtc), cookie) + return GetPanningCookie{cookie} +} + +// GetPanningUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPanningUnchecked(c *xgb.Conn, Crtc Crtc) GetPanningCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetPanning' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPanningRequest(c, Crtc), cookie) + return GetPanningCookie{cookie} +} + +// GetPanningReply represents the data returned from a GetPanning request. +type GetPanningReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + Timestamp xproto.Timestamp + Left uint16 + Top uint16 + Width uint16 + Height uint16 + TrackLeft uint16 + TrackTop uint16 + TrackWidth uint16 + TrackHeight uint16 + BorderLeft int16 + BorderTop int16 + BorderRight int16 + BorderBottom int16 +} + +// Reply blocks and returns the reply data for a GetPanning request. +func (cook GetPanningCookie) Reply() (*GetPanningReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPanningReply(buf), nil +} + +// getPanningReply reads a byte slice into a GetPanningReply value. +func getPanningReply(buf []byte) *GetPanningReply { + v := new(GetPanningReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Left = xgb.Get16(buf[b:]) + b += 2 + + v.Top = xgb.Get16(buf[b:]) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.TrackLeft = xgb.Get16(buf[b:]) + b += 2 + + v.TrackTop = xgb.Get16(buf[b:]) + b += 2 + + v.TrackWidth = xgb.Get16(buf[b:]) + b += 2 + + v.TrackHeight = xgb.Get16(buf[b:]) + b += 2 + + v.BorderLeft = int16(xgb.Get16(buf[b:])) + b += 2 + + v.BorderTop = int16(xgb.Get16(buf[b:])) + b += 2 + + v.BorderRight = int16(xgb.Get16(buf[b:])) + b += 2 + + v.BorderBottom = int16(xgb.Get16(buf[b:])) + b += 2 + + return v +} + +// Write request to wire for GetPanning +// getPanningRequest writes a GetPanning request to a byte slice. +func getPanningRequest(c *xgb.Conn, Crtc Crtc) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 28 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + return buf +} + +// GetProviderInfoCookie is a cookie used only for GetProviderInfo requests. +type GetProviderInfoCookie struct { + *xgb.Cookie +} + +// GetProviderInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetProviderInfoCookie.Reply() +func GetProviderInfo(c *xgb.Conn, Provider Provider, ConfigTimestamp xproto.Timestamp) GetProviderInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetProviderInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getProviderInfoRequest(c, Provider, ConfigTimestamp), cookie) + return GetProviderInfoCookie{cookie} +} + +// GetProviderInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetProviderInfoUnchecked(c *xgb.Conn, Provider Provider, ConfigTimestamp xproto.Timestamp) GetProviderInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetProviderInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getProviderInfoRequest(c, Provider, ConfigTimestamp), cookie) + return GetProviderInfoCookie{cookie} +} + +// GetProviderInfoReply represents the data returned from a GetProviderInfo request. +type GetProviderInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + Timestamp xproto.Timestamp + Capabilities uint32 + NumCrtcs uint16 + NumOutputs uint16 + NumAssociatedProviders uint16 + NameLen uint16 + // padding: 8 bytes + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + AssociatedProviders []Provider // size: xgb.Pad((int(NumAssociatedProviders) * 4)) + AssociatedCapability []uint32 // size: xgb.Pad((int(NumAssociatedProviders) * 4)) + Name string // size: xgb.Pad((int(NameLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetProviderInfo request. +func (cook GetProviderInfoCookie) Reply() (*GetProviderInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getProviderInfoReply(buf), nil +} + +// getProviderInfoReply reads a byte slice into a GetProviderInfoReply value. +func getProviderInfoReply(buf []byte) *GetProviderInfoReply { + v := new(GetProviderInfoReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Capabilities = xgb.Get32(buf[b:]) + b += 4 + + v.NumCrtcs = xgb.Get16(buf[b:]) + b += 2 + + v.NumOutputs = xgb.Get16(buf[b:]) + b += 2 + + v.NumAssociatedProviders = xgb.Get16(buf[b:]) + b += 2 + + v.NameLen = xgb.Get16(buf[b:]) + b += 2 + + b += 8 // padding + + v.Crtcs = make([]Crtc, v.NumCrtcs) + for i := 0; i < int(v.NumCrtcs); i++ { + v.Crtcs[i] = Crtc(xgb.Get32(buf[b:])) + b += 4 + } + + v.Outputs = make([]Output, v.NumOutputs) + for i := 0; i < int(v.NumOutputs); i++ { + v.Outputs[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + v.AssociatedProviders = make([]Provider, v.NumAssociatedProviders) + for i := 0; i < int(v.NumAssociatedProviders); i++ { + v.AssociatedProviders[i] = Provider(xgb.Get32(buf[b:])) + b += 4 + } + + v.AssociatedCapability = make([]uint32, v.NumAssociatedProviders) + for i := 0; i < int(v.NumAssociatedProviders); i++ { + v.AssociatedCapability[i] = xgb.Get32(buf[b:]) + b += 4 + } + + { + byteString := make([]byte, v.NameLen) + copy(byteString[:v.NameLen], buf[b:]) + v.Name = string(byteString) + b += int(v.NameLen) + } + + return v +} + +// Write request to wire for GetProviderInfo +// getProviderInfoRequest writes a GetProviderInfo request to a byte slice. +func getProviderInfoRequest(c *xgb.Conn, Provider Provider, ConfigTimestamp xproto.Timestamp) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 33 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + return buf +} + +// GetProviderPropertyCookie is a cookie used only for GetProviderProperty requests. +type GetProviderPropertyCookie struct { + *xgb.Cookie +} + +// GetProviderProperty sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetProviderPropertyCookie.Reply() +func GetProviderProperty(c *xgb.Conn, Provider Provider, Property xproto.Atom, Type xproto.Atom, LongOffset uint32, LongLength uint32, Delete bool, Pending bool) GetProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getProviderPropertyRequest(c, Provider, Property, Type, LongOffset, LongLength, Delete, Pending), cookie) + return GetProviderPropertyCookie{cookie} +} + +// GetProviderPropertyUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetProviderPropertyUnchecked(c *xgb.Conn, Provider Provider, Property xproto.Atom, Type xproto.Atom, LongOffset uint32, LongLength uint32, Delete bool, Pending bool) GetProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getProviderPropertyRequest(c, Provider, Property, Type, LongOffset, LongLength, Delete, Pending), cookie) + return GetProviderPropertyCookie{cookie} +} + +// GetProviderPropertyReply represents the data returned from a GetProviderProperty request. +type GetProviderPropertyReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Format byte + Type xproto.Atom + BytesAfter uint32 + NumItems uint32 + // padding: 12 bytes + Data []byte // size: xgb.Pad(((int(NumItems) * (int(Format) / 8)) * 1)) +} + +// Reply blocks and returns the reply data for a GetProviderProperty request. +func (cook GetProviderPropertyCookie) Reply() (*GetProviderPropertyReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getProviderPropertyReply(buf), nil +} + +// getProviderPropertyReply reads a byte slice into a GetProviderPropertyReply value. +func getProviderPropertyReply(buf []byte) *GetProviderPropertyReply { + v := new(GetProviderPropertyReply) + b := 1 // skip reply determinant + + v.Format = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Type = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.BytesAfter = xgb.Get32(buf[b:]) + b += 4 + + v.NumItems = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Data = make([]byte, (int(v.NumItems) * (int(v.Format) / 8))) + copy(v.Data[:(int(v.NumItems)*(int(v.Format)/8))], buf[b:]) + b += int((int(v.NumItems) * (int(v.Format) / 8))) + + return v +} + +// Write request to wire for GetProviderProperty +// getProviderPropertyRequest writes a GetProviderProperty request to a byte slice. +func getProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property xproto.Atom, Type xproto.Atom, LongOffset uint32, LongLength uint32, Delete bool, Pending bool) []byte { + size := 28 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 41 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + xgb.Put32(buf[b:], LongOffset) + b += 4 + + xgb.Put32(buf[b:], LongLength) + b += 4 + + if Delete { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if Pending { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 2 // padding + + return buf +} + +// GetProvidersCookie is a cookie used only for GetProviders requests. +type GetProvidersCookie struct { + *xgb.Cookie +} + +// GetProviders sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetProvidersCookie.Reply() +func GetProviders(c *xgb.Conn, Window xproto.Window) GetProvidersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetProviders' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getProvidersRequest(c, Window), cookie) + return GetProvidersCookie{cookie} +} + +// GetProvidersUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetProvidersUnchecked(c *xgb.Conn, Window xproto.Window) GetProvidersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetProviders' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getProvidersRequest(c, Window), cookie) + return GetProvidersCookie{cookie} +} + +// GetProvidersReply represents the data returned from a GetProviders request. +type GetProvidersReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Timestamp xproto.Timestamp + NumProviders uint16 + // padding: 18 bytes + Providers []Provider // size: xgb.Pad((int(NumProviders) * 4)) +} + +// Reply blocks and returns the reply data for a GetProviders request. +func (cook GetProvidersCookie) Reply() (*GetProvidersReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getProvidersReply(buf), nil +} + +// getProvidersReply reads a byte slice into a GetProvidersReply value. +func getProvidersReply(buf []byte) *GetProvidersReply { + v := new(GetProvidersReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.NumProviders = xgb.Get16(buf[b:]) + b += 2 + + b += 18 // padding + + v.Providers = make([]Provider, v.NumProviders) + for i := 0; i < int(v.NumProviders); i++ { + v.Providers[i] = Provider(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetProviders +// getProvidersRequest writes a GetProviders request to a byte slice. +func getProvidersRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 32 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetScreenInfoCookie is a cookie used only for GetScreenInfo requests. +type GetScreenInfoCookie struct { + *xgb.Cookie +} + +// GetScreenInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenInfoCookie.Reply() +func GetScreenInfo(c *xgb.Conn, Window xproto.Window) GetScreenInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenInfoRequest(c, Window), cookie) + return GetScreenInfoCookie{cookie} +} + +// GetScreenInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenInfoUnchecked(c *xgb.Conn, Window xproto.Window) GetScreenInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenInfo' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenInfoRequest(c, Window), cookie) + return GetScreenInfoCookie{cookie} +} + +// GetScreenInfoReply represents the data returned from a GetScreenInfo request. +type GetScreenInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Rotations byte + Root xproto.Window + Timestamp xproto.Timestamp + ConfigTimestamp xproto.Timestamp + NSizes uint16 + SizeID uint16 + Rotation uint16 + Rate uint16 + NInfo uint16 + // padding: 2 bytes + Sizes []ScreenSize // size: xgb.Pad((int(NSizes) * 8)) + Rates []RefreshRates // size: RefreshRatesListSize(Rates) +} + +// Reply blocks and returns the reply data for a GetScreenInfo request. +func (cook GetScreenInfoCookie) Reply() (*GetScreenInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenInfoReply(buf), nil +} + +// getScreenInfoReply reads a byte slice into a GetScreenInfoReply value. +func getScreenInfoReply(buf []byte) *GetScreenInfoReply { + v := new(GetScreenInfoReply) + b := 1 // skip reply determinant + + v.Rotations = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Root = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.ConfigTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.NSizes = xgb.Get16(buf[b:]) + b += 2 + + v.SizeID = xgb.Get16(buf[b:]) + b += 2 + + v.Rotation = xgb.Get16(buf[b:]) + b += 2 + + v.Rate = xgb.Get16(buf[b:]) + b += 2 + + v.NInfo = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Sizes = make([]ScreenSize, v.NSizes) + b += ScreenSizeReadList(buf[b:], v.Sizes) + + v.Rates = make([]RefreshRates, (int(v.NInfo) - int(v.NSizes))) + b += RefreshRatesReadList(buf[b:], v.Rates) + + return v +} + +// Write request to wire for GetScreenInfo +// getScreenInfoRequest writes a GetScreenInfo request to a byte slice. +func getScreenInfoRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetScreenResourcesCookie is a cookie used only for GetScreenResources requests. +type GetScreenResourcesCookie struct { + *xgb.Cookie +} + +// GetScreenResources sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenResourcesCookie.Reply() +func GetScreenResources(c *xgb.Conn, Window xproto.Window) GetScreenResourcesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenResources' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenResourcesRequest(c, Window), cookie) + return GetScreenResourcesCookie{cookie} +} + +// GetScreenResourcesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenResourcesUnchecked(c *xgb.Conn, Window xproto.Window) GetScreenResourcesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenResources' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenResourcesRequest(c, Window), cookie) + return GetScreenResourcesCookie{cookie} +} + +// GetScreenResourcesReply represents the data returned from a GetScreenResources request. +type GetScreenResourcesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Timestamp xproto.Timestamp + ConfigTimestamp xproto.Timestamp + NumCrtcs uint16 + NumOutputs uint16 + NumModes uint16 + NamesLen uint16 + // padding: 8 bytes + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + Modes []ModeInfo // size: xgb.Pad((int(NumModes) * 32)) + Names []byte // size: xgb.Pad((int(NamesLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetScreenResources request. +func (cook GetScreenResourcesCookie) Reply() (*GetScreenResourcesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenResourcesReply(buf), nil +} + +// getScreenResourcesReply reads a byte slice into a GetScreenResourcesReply value. +func getScreenResourcesReply(buf []byte) *GetScreenResourcesReply { + v := new(GetScreenResourcesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.ConfigTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.NumCrtcs = xgb.Get16(buf[b:]) + b += 2 + + v.NumOutputs = xgb.Get16(buf[b:]) + b += 2 + + v.NumModes = xgb.Get16(buf[b:]) + b += 2 + + v.NamesLen = xgb.Get16(buf[b:]) + b += 2 + + b += 8 // padding + + v.Crtcs = make([]Crtc, v.NumCrtcs) + for i := 0; i < int(v.NumCrtcs); i++ { + v.Crtcs[i] = Crtc(xgb.Get32(buf[b:])) + b += 4 + } + + v.Outputs = make([]Output, v.NumOutputs) + for i := 0; i < int(v.NumOutputs); i++ { + v.Outputs[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + v.Modes = make([]ModeInfo, v.NumModes) + b += ModeInfoReadList(buf[b:], v.Modes) + + v.Names = make([]byte, v.NamesLen) + copy(v.Names[:v.NamesLen], buf[b:]) + b += int(v.NamesLen) + + return v +} + +// Write request to wire for GetScreenResources +// getScreenResourcesRequest writes a GetScreenResources request to a byte slice. +func getScreenResourcesRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetScreenResourcesCurrentCookie is a cookie used only for GetScreenResourcesCurrent requests. +type GetScreenResourcesCurrentCookie struct { + *xgb.Cookie +} + +// GetScreenResourcesCurrent sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenResourcesCurrentCookie.Reply() +func GetScreenResourcesCurrent(c *xgb.Conn, Window xproto.Window) GetScreenResourcesCurrentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenResourcesCurrent' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenResourcesCurrentRequest(c, Window), cookie) + return GetScreenResourcesCurrentCookie{cookie} +} + +// GetScreenResourcesCurrentUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenResourcesCurrentUnchecked(c *xgb.Conn, Window xproto.Window) GetScreenResourcesCurrentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenResourcesCurrent' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenResourcesCurrentRequest(c, Window), cookie) + return GetScreenResourcesCurrentCookie{cookie} +} + +// GetScreenResourcesCurrentReply represents the data returned from a GetScreenResourcesCurrent request. +type GetScreenResourcesCurrentReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Timestamp xproto.Timestamp + ConfigTimestamp xproto.Timestamp + NumCrtcs uint16 + NumOutputs uint16 + NumModes uint16 + NamesLen uint16 + // padding: 8 bytes + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + Modes []ModeInfo // size: xgb.Pad((int(NumModes) * 32)) + Names []byte // size: xgb.Pad((int(NamesLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetScreenResourcesCurrent request. +func (cook GetScreenResourcesCurrentCookie) Reply() (*GetScreenResourcesCurrentReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenResourcesCurrentReply(buf), nil +} + +// getScreenResourcesCurrentReply reads a byte slice into a GetScreenResourcesCurrentReply value. +func getScreenResourcesCurrentReply(buf []byte) *GetScreenResourcesCurrentReply { + v := new(GetScreenResourcesCurrentReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.ConfigTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.NumCrtcs = xgb.Get16(buf[b:]) + b += 2 + + v.NumOutputs = xgb.Get16(buf[b:]) + b += 2 + + v.NumModes = xgb.Get16(buf[b:]) + b += 2 + + v.NamesLen = xgb.Get16(buf[b:]) + b += 2 + + b += 8 // padding + + v.Crtcs = make([]Crtc, v.NumCrtcs) + for i := 0; i < int(v.NumCrtcs); i++ { + v.Crtcs[i] = Crtc(xgb.Get32(buf[b:])) + b += 4 + } + + v.Outputs = make([]Output, v.NumOutputs) + for i := 0; i < int(v.NumOutputs); i++ { + v.Outputs[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + v.Modes = make([]ModeInfo, v.NumModes) + b += ModeInfoReadList(buf[b:], v.Modes) + + v.Names = make([]byte, v.NamesLen) + copy(v.Names[:v.NamesLen], buf[b:]) + b += int(v.NamesLen) + + return v +} + +// Write request to wire for GetScreenResourcesCurrent +// getScreenResourcesCurrentRequest writes a GetScreenResourcesCurrent request to a byte slice. +func getScreenResourcesCurrentRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 25 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetScreenSizeRangeCookie is a cookie used only for GetScreenSizeRange requests. +type GetScreenSizeRangeCookie struct { + *xgb.Cookie +} + +// GetScreenSizeRange sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenSizeRangeCookie.Reply() +func GetScreenSizeRange(c *xgb.Conn, Window xproto.Window) GetScreenSizeRangeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenSizeRange' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenSizeRangeRequest(c, Window), cookie) + return GetScreenSizeRangeCookie{cookie} +} + +// GetScreenSizeRangeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenSizeRangeUnchecked(c *xgb.Conn, Window xproto.Window) GetScreenSizeRangeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetScreenSizeRange' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenSizeRangeRequest(c, Window), cookie) + return GetScreenSizeRangeCookie{cookie} +} + +// GetScreenSizeRangeReply represents the data returned from a GetScreenSizeRange request. +type GetScreenSizeRangeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MinWidth uint16 + MinHeight uint16 + MaxWidth uint16 + MaxHeight uint16 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a GetScreenSizeRange request. +func (cook GetScreenSizeRangeCookie) Reply() (*GetScreenSizeRangeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenSizeRangeReply(buf), nil +} + +// getScreenSizeRangeReply reads a byte slice into a GetScreenSizeRangeReply value. +func getScreenSizeRangeReply(buf []byte) *GetScreenSizeRangeReply { + v := new(GetScreenSizeRangeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MinWidth = xgb.Get16(buf[b:]) + b += 2 + + v.MinHeight = xgb.Get16(buf[b:]) + b += 2 + + v.MaxWidth = xgb.Get16(buf[b:]) + b += 2 + + v.MaxHeight = xgb.Get16(buf[b:]) + b += 2 + + b += 16 // padding + + return v +} + +// Write request to wire for GetScreenSizeRange +// getScreenSizeRangeRequest writes a GetScreenSizeRange request to a byte slice. +func getScreenSizeRangeRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// ListOutputPropertiesCookie is a cookie used only for ListOutputProperties requests. +type ListOutputPropertiesCookie struct { + *xgb.Cookie +} + +// ListOutputProperties sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListOutputPropertiesCookie.Reply() +func ListOutputProperties(c *xgb.Conn, Output Output) ListOutputPropertiesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ListOutputProperties' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listOutputPropertiesRequest(c, Output), cookie) + return ListOutputPropertiesCookie{cookie} +} + +// ListOutputPropertiesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListOutputPropertiesUnchecked(c *xgb.Conn, Output Output) ListOutputPropertiesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ListOutputProperties' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listOutputPropertiesRequest(c, Output), cookie) + return ListOutputPropertiesCookie{cookie} +} + +// ListOutputPropertiesReply represents the data returned from a ListOutputProperties request. +type ListOutputPropertiesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAtoms uint16 + // padding: 22 bytes + Atoms []xproto.Atom // size: xgb.Pad((int(NumAtoms) * 4)) +} + +// Reply blocks and returns the reply data for a ListOutputProperties request. +func (cook ListOutputPropertiesCookie) Reply() (*ListOutputPropertiesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listOutputPropertiesReply(buf), nil +} + +// listOutputPropertiesReply reads a byte slice into a ListOutputPropertiesReply value. +func listOutputPropertiesReply(buf []byte) *ListOutputPropertiesReply { + v := new(ListOutputPropertiesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAtoms = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Atoms = make([]xproto.Atom, v.NumAtoms) + for i := 0; i < int(v.NumAtoms); i++ { + v.Atoms[i] = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for ListOutputProperties +// listOutputPropertiesRequest writes a ListOutputProperties request to a byte slice. +func listOutputPropertiesRequest(c *xgb.Conn, Output Output) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + return buf +} + +// ListProviderPropertiesCookie is a cookie used only for ListProviderProperties requests. +type ListProviderPropertiesCookie struct { + *xgb.Cookie +} + +// ListProviderProperties sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListProviderPropertiesCookie.Reply() +func ListProviderProperties(c *xgb.Conn, Provider Provider) ListProviderPropertiesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ListProviderProperties' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listProviderPropertiesRequest(c, Provider), cookie) + return ListProviderPropertiesCookie{cookie} +} + +// ListProviderPropertiesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListProviderPropertiesUnchecked(c *xgb.Conn, Provider Provider) ListProviderPropertiesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'ListProviderProperties' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listProviderPropertiesRequest(c, Provider), cookie) + return ListProviderPropertiesCookie{cookie} +} + +// ListProviderPropertiesReply represents the data returned from a ListProviderProperties request. +type ListProviderPropertiesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAtoms uint16 + // padding: 22 bytes + Atoms []xproto.Atom // size: xgb.Pad((int(NumAtoms) * 4)) +} + +// Reply blocks and returns the reply data for a ListProviderProperties request. +func (cook ListProviderPropertiesCookie) Reply() (*ListProviderPropertiesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listProviderPropertiesReply(buf), nil +} + +// listProviderPropertiesReply reads a byte slice into a ListProviderPropertiesReply value. +func listProviderPropertiesReply(buf []byte) *ListProviderPropertiesReply { + v := new(ListProviderPropertiesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAtoms = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Atoms = make([]xproto.Atom, v.NumAtoms) + for i := 0; i < int(v.NumAtoms); i++ { + v.Atoms[i] = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for ListProviderProperties +// listProviderPropertiesRequest writes a ListProviderProperties request to a byte slice. +func listProviderPropertiesRequest(c *xgb.Conn, Provider Provider) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 36 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + return buf +} + +// QueryOutputPropertyCookie is a cookie used only for QueryOutputProperty requests. +type QueryOutputPropertyCookie struct { + *xgb.Cookie +} + +// QueryOutputProperty sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryOutputPropertyCookie.Reply() +func QueryOutputProperty(c *xgb.Conn, Output Output, Property xproto.Atom) QueryOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'QueryOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryOutputPropertyRequest(c, Output, Property), cookie) + return QueryOutputPropertyCookie{cookie} +} + +// QueryOutputPropertyUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryOutputPropertyUnchecked(c *xgb.Conn, Output Output, Property xproto.Atom) QueryOutputPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'QueryOutputProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryOutputPropertyRequest(c, Output, Property), cookie) + return QueryOutputPropertyCookie{cookie} +} + +// QueryOutputPropertyReply represents the data returned from a QueryOutputProperty request. +type QueryOutputPropertyReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Pending bool + Range bool + Immutable bool + // padding: 21 bytes + ValidValues []int32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a QueryOutputProperty request. +func (cook QueryOutputPropertyCookie) Reply() (*QueryOutputPropertyReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryOutputPropertyReply(buf), nil +} + +// queryOutputPropertyReply reads a byte slice into a QueryOutputPropertyReply value. +func queryOutputPropertyReply(buf []byte) *QueryOutputPropertyReply { + v := new(QueryOutputPropertyReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.Pending = true + } else { + v.Pending = false + } + b += 1 + + if buf[b] == 1 { + v.Range = true + } else { + v.Range = false + } + b += 1 + + if buf[b] == 1 { + v.Immutable = true + } else { + v.Immutable = false + } + b += 1 + + b += 21 // padding + + v.ValidValues = make([]int32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.ValidValues[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for QueryOutputProperty +// queryOutputPropertyRequest writes a QueryOutputProperty request to a byte slice. +func queryOutputPropertyRequest(c *xgb.Conn, Output Output, Property xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// QueryProviderPropertyCookie is a cookie used only for QueryProviderProperty requests. +type QueryProviderPropertyCookie struct { + *xgb.Cookie +} + +// QueryProviderProperty sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryProviderPropertyCookie.Reply() +func QueryProviderProperty(c *xgb.Conn, Provider Provider, Property xproto.Atom) QueryProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'QueryProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryProviderPropertyRequest(c, Provider, Property), cookie) + return QueryProviderPropertyCookie{cookie} +} + +// QueryProviderPropertyUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryProviderPropertyUnchecked(c *xgb.Conn, Provider Provider, Property xproto.Atom) QueryProviderPropertyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'QueryProviderProperty' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryProviderPropertyRequest(c, Provider, Property), cookie) + return QueryProviderPropertyCookie{cookie} +} + +// QueryProviderPropertyReply represents the data returned from a QueryProviderProperty request. +type QueryProviderPropertyReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Pending bool + Range bool + Immutable bool + // padding: 21 bytes + ValidValues []int32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a QueryProviderProperty request. +func (cook QueryProviderPropertyCookie) Reply() (*QueryProviderPropertyReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryProviderPropertyReply(buf), nil +} + +// queryProviderPropertyReply reads a byte slice into a QueryProviderPropertyReply value. +func queryProviderPropertyReply(buf []byte) *QueryProviderPropertyReply { + v := new(QueryProviderPropertyReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.Pending = true + } else { + v.Pending = false + } + b += 1 + + if buf[b] == 1 { + v.Range = true + } else { + v.Range = false + } + b += 1 + + if buf[b] == 1 { + v.Immutable = true + } else { + v.Immutable = false + } + b += 1 + + b += 21 // padding + + v.ValidValues = make([]int32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.ValidValues[i] = int32(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for QueryProviderProperty +// queryProviderPropertyRequest writes a QueryProviderProperty request to a byte slice. +func queryProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 37 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + return buf +} + +// SelectInputCookie is a cookie used only for SelectInput requests. +type SelectInputCookie struct { + *xgb.Cookie +} + +// SelectInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectInput(c *xgb.Conn, Window xproto.Window, Enable uint16) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectInputRequest(c, Window, Enable), cookie) + return SelectInputCookie{cookie} +} + +// SelectInputChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectInputCookie.Check() +func SelectInputChecked(c *xgb.Conn, Window xproto.Window, Enable uint16) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectInputRequest(c, Window, Enable), cookie) + return SelectInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectInput +// selectInputRequest writes a SelectInput request to a byte slice. +func selectInputRequest(c *xgb.Conn, Window xproto.Window, Enable uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put16(buf[b:], Enable) + b += 2 + + b += 2 // padding + + return buf +} + +// SetCrtcConfigCookie is a cookie used only for SetCrtcConfig requests. +type SetCrtcConfigCookie struct { + *xgb.Cookie +} + +// SetCrtcConfig sends a checked request. +// If an error occurs, it will be returned with the reply by calling SetCrtcConfigCookie.Reply() +func SetCrtcConfig(c *xgb.Conn, Crtc Crtc, Timestamp xproto.Timestamp, ConfigTimestamp xproto.Timestamp, X int16, Y int16, Mode Mode, Rotation uint16, Outputs []Output) SetCrtcConfigCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetCrtcConfig' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(setCrtcConfigRequest(c, Crtc, Timestamp, ConfigTimestamp, X, Y, Mode, Rotation, Outputs), cookie) + return SetCrtcConfigCookie{cookie} +} + +// SetCrtcConfigUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetCrtcConfigUnchecked(c *xgb.Conn, Crtc Crtc, Timestamp xproto.Timestamp, ConfigTimestamp xproto.Timestamp, X int16, Y int16, Mode Mode, Rotation uint16, Outputs []Output) SetCrtcConfigCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetCrtcConfig' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(setCrtcConfigRequest(c, Crtc, Timestamp, ConfigTimestamp, X, Y, Mode, Rotation, Outputs), cookie) + return SetCrtcConfigCookie{cookie} +} + +// SetCrtcConfigReply represents the data returned from a SetCrtcConfig request. +type SetCrtcConfigReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + Timestamp xproto.Timestamp + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a SetCrtcConfig request. +func (cook SetCrtcConfigCookie) Reply() (*SetCrtcConfigReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return setCrtcConfigReply(buf), nil +} + +// setCrtcConfigReply reads a byte slice into a SetCrtcConfigReply value. +func setCrtcConfigReply(buf []byte) *SetCrtcConfigReply { + v := new(SetCrtcConfigReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for SetCrtcConfig +// setCrtcConfigRequest writes a SetCrtcConfig request to a byte slice. +func setCrtcConfigRequest(c *xgb.Conn, Crtc Crtc, Timestamp xproto.Timestamp, ConfigTimestamp xproto.Timestamp, X int16, Y int16, Mode Mode, Rotation uint16, Outputs []Output) []byte { + size := xgb.Pad((28 + xgb.Pad((len(Outputs) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 21 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + xgb.Put32(buf[b:], uint32(Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + xgb.Put32(buf[b:], uint32(Mode)) + b += 4 + + xgb.Put16(buf[b:], Rotation) + b += 2 + + b += 2 // padding + + for i := 0; i < int(len(Outputs)); i++ { + xgb.Put32(buf[b:], uint32(Outputs[i])) + b += 4 + } + + return buf +} + +// SetCrtcGammaCookie is a cookie used only for SetCrtcGamma requests. +type SetCrtcGammaCookie struct { + *xgb.Cookie +} + +// SetCrtcGamma sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetCrtcGamma(c *xgb.Conn, Crtc Crtc, Size uint16, Red []uint16, Green []uint16, Blue []uint16) SetCrtcGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetCrtcGamma' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setCrtcGammaRequest(c, Crtc, Size, Red, Green, Blue), cookie) + return SetCrtcGammaCookie{cookie} +} + +// SetCrtcGammaChecked sends a checked request. +// If an error occurs, it can be retrieved using SetCrtcGammaCookie.Check() +func SetCrtcGammaChecked(c *xgb.Conn, Crtc Crtc, Size uint16, Red []uint16, Green []uint16, Blue []uint16) SetCrtcGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetCrtcGamma' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setCrtcGammaRequest(c, Crtc, Size, Red, Green, Blue), cookie) + return SetCrtcGammaCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetCrtcGammaCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetCrtcGamma +// setCrtcGammaRequest writes a SetCrtcGamma request to a byte slice. +func setCrtcGammaRequest(c *xgb.Conn, Crtc Crtc, Size uint16, Red []uint16, Green []uint16, Blue []uint16) []byte { + size := xgb.Pad((((12 + xgb.Pad((int(Size) * 2))) + xgb.Pad((int(Size) * 2))) + xgb.Pad((int(Size) * 2)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 24 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + xgb.Put16(buf[b:], Size) + b += 2 + + b += 2 // padding + + for i := 0; i < int(Size); i++ { + xgb.Put16(buf[b:], Red[i]) + b += 2 + } + + for i := 0; i < int(Size); i++ { + xgb.Put16(buf[b:], Green[i]) + b += 2 + } + + for i := 0; i < int(Size); i++ { + xgb.Put16(buf[b:], Blue[i]) + b += 2 + } + + return buf +} + +// SetCrtcTransformCookie is a cookie used only for SetCrtcTransform requests. +type SetCrtcTransformCookie struct { + *xgb.Cookie +} + +// SetCrtcTransform sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetCrtcTransform(c *xgb.Conn, Crtc Crtc, Transform render.Transform, FilterLen uint16, FilterName string, FilterParams []render.Fixed) SetCrtcTransformCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetCrtcTransform' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setCrtcTransformRequest(c, Crtc, Transform, FilterLen, FilterName, FilterParams), cookie) + return SetCrtcTransformCookie{cookie} +} + +// SetCrtcTransformChecked sends a checked request. +// If an error occurs, it can be retrieved using SetCrtcTransformCookie.Check() +func SetCrtcTransformChecked(c *xgb.Conn, Crtc Crtc, Transform render.Transform, FilterLen uint16, FilterName string, FilterParams []render.Fixed) SetCrtcTransformCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetCrtcTransform' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setCrtcTransformRequest(c, Crtc, Transform, FilterLen, FilterName, FilterParams), cookie) + return SetCrtcTransformCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetCrtcTransformCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetCrtcTransform +// setCrtcTransformRequest writes a SetCrtcTransform request to a byte slice. +func setCrtcTransformRequest(c *xgb.Conn, Crtc Crtc, Transform render.Transform, FilterLen uint16, FilterName string, FilterParams []render.Fixed) []byte { + size := xgb.Pad((((48 + xgb.Pad((int(FilterLen) * 1))) + 4) + xgb.Pad((len(FilterParams) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 26 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + { + structBytes := Transform.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put16(buf[b:], FilterLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], FilterName[:FilterLen]) + b += int(FilterLen) + + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(len(FilterParams)); i++ { + xgb.Put32(buf[b:], uint32(FilterParams[i])) + b += 4 + } + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// SetMonitorCookie is a cookie used only for SetMonitor requests. +type SetMonitorCookie struct { + *xgb.Cookie +} + +// SetMonitor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetMonitor(c *xgb.Conn, Window xproto.Window, Monitorinfo MonitorInfo) SetMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setMonitorRequest(c, Window, Monitorinfo), cookie) + return SetMonitorCookie{cookie} +} + +// SetMonitorChecked sends a checked request. +// If an error occurs, it can be retrieved using SetMonitorCookie.Check() +func SetMonitorChecked(c *xgb.Conn, Window xproto.Window, Monitorinfo MonitorInfo) SetMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setMonitorRequest(c, Window, Monitorinfo), cookie) + return SetMonitorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetMonitorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetMonitor +// setMonitorRequest writes a SetMonitor request to a byte slice. +func setMonitorRequest(c *xgb.Conn, Window xproto.Window, Monitorinfo MonitorInfo) []byte { + size := xgb.Pad((8 + (24 + xgb.Pad((int(Monitorinfo.NOutput) * 4))))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 43 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + { + structBytes := Monitorinfo.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf +} + +// SetOutputPrimaryCookie is a cookie used only for SetOutputPrimary requests. +type SetOutputPrimaryCookie struct { + *xgb.Cookie +} + +// SetOutputPrimary sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetOutputPrimary(c *xgb.Conn, Window xproto.Window, Output Output) SetOutputPrimaryCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetOutputPrimary' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setOutputPrimaryRequest(c, Window, Output), cookie) + return SetOutputPrimaryCookie{cookie} +} + +// SetOutputPrimaryChecked sends a checked request. +// If an error occurs, it can be retrieved using SetOutputPrimaryCookie.Check() +func SetOutputPrimaryChecked(c *xgb.Conn, Window xproto.Window, Output Output) SetOutputPrimaryCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetOutputPrimary' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setOutputPrimaryRequest(c, Window, Output), cookie) + return SetOutputPrimaryCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetOutputPrimaryCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetOutputPrimary +// setOutputPrimaryRequest writes a SetOutputPrimary request to a byte slice. +func setOutputPrimaryRequest(c *xgb.Conn, Window xproto.Window, Output Output) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 30 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Output)) + b += 4 + + return buf +} + +// SetPanningCookie is a cookie used only for SetPanning requests. +type SetPanningCookie struct { + *xgb.Cookie +} + +// SetPanning sends a checked request. +// If an error occurs, it will be returned with the reply by calling SetPanningCookie.Reply() +func SetPanning(c *xgb.Conn, Crtc Crtc, Timestamp xproto.Timestamp, Left uint16, Top uint16, Width uint16, Height uint16, TrackLeft uint16, TrackTop uint16, TrackWidth uint16, TrackHeight uint16, BorderLeft int16, BorderTop int16, BorderRight int16, BorderBottom int16) SetPanningCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetPanning' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(setPanningRequest(c, Crtc, Timestamp, Left, Top, Width, Height, TrackLeft, TrackTop, TrackWidth, TrackHeight, BorderLeft, BorderTop, BorderRight, BorderBottom), cookie) + return SetPanningCookie{cookie} +} + +// SetPanningUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPanningUnchecked(c *xgb.Conn, Crtc Crtc, Timestamp xproto.Timestamp, Left uint16, Top uint16, Width uint16, Height uint16, TrackLeft uint16, TrackTop uint16, TrackWidth uint16, TrackHeight uint16, BorderLeft int16, BorderTop int16, BorderRight int16, BorderBottom int16) SetPanningCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetPanning' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(setPanningRequest(c, Crtc, Timestamp, Left, Top, Width, Height, TrackLeft, TrackTop, TrackWidth, TrackHeight, BorderLeft, BorderTop, BorderRight, BorderBottom), cookie) + return SetPanningCookie{cookie} +} + +// SetPanningReply represents the data returned from a SetPanning request. +type SetPanningReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + Timestamp xproto.Timestamp +} + +// Reply blocks and returns the reply data for a SetPanning request. +func (cook SetPanningCookie) Reply() (*SetPanningReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return setPanningReply(buf), nil +} + +// setPanningReply reads a byte slice into a SetPanningReply value. +func setPanningReply(buf []byte) *SetPanningReply { + v := new(SetPanningReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for SetPanning +// setPanningRequest writes a SetPanning request to a byte slice. +func setPanningRequest(c *xgb.Conn, Crtc Crtc, Timestamp xproto.Timestamp, Left uint16, Top uint16, Width uint16, Height uint16, TrackLeft uint16, TrackTop uint16, TrackWidth uint16, TrackHeight uint16, BorderLeft int16, BorderTop int16, BorderRight int16, BorderBottom int16) []byte { + size := 36 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 29 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Crtc)) + b += 4 + + xgb.Put32(buf[b:], uint32(Timestamp)) + b += 4 + + xgb.Put16(buf[b:], Left) + b += 2 + + xgb.Put16(buf[b:], Top) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put16(buf[b:], TrackLeft) + b += 2 + + xgb.Put16(buf[b:], TrackTop) + b += 2 + + xgb.Put16(buf[b:], TrackWidth) + b += 2 + + xgb.Put16(buf[b:], TrackHeight) + b += 2 + + xgb.Put16(buf[b:], uint16(BorderLeft)) + b += 2 + + xgb.Put16(buf[b:], uint16(BorderTop)) + b += 2 + + xgb.Put16(buf[b:], uint16(BorderRight)) + b += 2 + + xgb.Put16(buf[b:], uint16(BorderBottom)) + b += 2 + + return buf +} + +// SetProviderOffloadSinkCookie is a cookie used only for SetProviderOffloadSink requests. +type SetProviderOffloadSinkCookie struct { + *xgb.Cookie +} + +// SetProviderOffloadSink sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetProviderOffloadSink(c *xgb.Conn, Provider Provider, SinkProvider Provider, ConfigTimestamp xproto.Timestamp) SetProviderOffloadSinkCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetProviderOffloadSink' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setProviderOffloadSinkRequest(c, Provider, SinkProvider, ConfigTimestamp), cookie) + return SetProviderOffloadSinkCookie{cookie} +} + +// SetProviderOffloadSinkChecked sends a checked request. +// If an error occurs, it can be retrieved using SetProviderOffloadSinkCookie.Check() +func SetProviderOffloadSinkChecked(c *xgb.Conn, Provider Provider, SinkProvider Provider, ConfigTimestamp xproto.Timestamp) SetProviderOffloadSinkCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetProviderOffloadSink' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setProviderOffloadSinkRequest(c, Provider, SinkProvider, ConfigTimestamp), cookie) + return SetProviderOffloadSinkCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetProviderOffloadSinkCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetProviderOffloadSink +// setProviderOffloadSinkRequest writes a SetProviderOffloadSink request to a byte slice. +func setProviderOffloadSinkRequest(c *xgb.Conn, Provider Provider, SinkProvider Provider, ConfigTimestamp xproto.Timestamp) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 34 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(SinkProvider)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + return buf +} + +// SetProviderOutputSourceCookie is a cookie used only for SetProviderOutputSource requests. +type SetProviderOutputSourceCookie struct { + *xgb.Cookie +} + +// SetProviderOutputSource sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetProviderOutputSource(c *xgb.Conn, Provider Provider, SourceProvider Provider, ConfigTimestamp xproto.Timestamp) SetProviderOutputSourceCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetProviderOutputSource' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setProviderOutputSourceRequest(c, Provider, SourceProvider, ConfigTimestamp), cookie) + return SetProviderOutputSourceCookie{cookie} +} + +// SetProviderOutputSourceChecked sends a checked request. +// If an error occurs, it can be retrieved using SetProviderOutputSourceCookie.Check() +func SetProviderOutputSourceChecked(c *xgb.Conn, Provider Provider, SourceProvider Provider, ConfigTimestamp xproto.Timestamp) SetProviderOutputSourceCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetProviderOutputSource' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setProviderOutputSourceRequest(c, Provider, SourceProvider, ConfigTimestamp), cookie) + return SetProviderOutputSourceCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetProviderOutputSourceCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetProviderOutputSource +// setProviderOutputSourceRequest writes a SetProviderOutputSource request to a byte slice. +func setProviderOutputSourceRequest(c *xgb.Conn, Provider Provider, SourceProvider Provider, ConfigTimestamp xproto.Timestamp) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 35 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Provider)) + b += 4 + + xgb.Put32(buf[b:], uint32(SourceProvider)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + return buf +} + +// SetScreenConfigCookie is a cookie used only for SetScreenConfig requests. +type SetScreenConfigCookie struct { + *xgb.Cookie +} + +// SetScreenConfig sends a checked request. +// If an error occurs, it will be returned with the reply by calling SetScreenConfigCookie.Reply() +func SetScreenConfig(c *xgb.Conn, Window xproto.Window, Timestamp xproto.Timestamp, ConfigTimestamp xproto.Timestamp, SizeID uint16, Rotation uint16, Rate uint16) SetScreenConfigCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetScreenConfig' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(setScreenConfigRequest(c, Window, Timestamp, ConfigTimestamp, SizeID, Rotation, Rate), cookie) + return SetScreenConfigCookie{cookie} +} + +// SetScreenConfigUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetScreenConfigUnchecked(c *xgb.Conn, Window xproto.Window, Timestamp xproto.Timestamp, ConfigTimestamp xproto.Timestamp, SizeID uint16, Rotation uint16, Rate uint16) SetScreenConfigCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetScreenConfig' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(setScreenConfigRequest(c, Window, Timestamp, ConfigTimestamp, SizeID, Rotation, Rate), cookie) + return SetScreenConfigCookie{cookie} +} + +// SetScreenConfigReply represents the data returned from a SetScreenConfig request. +type SetScreenConfigReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte + NewTimestamp xproto.Timestamp + ConfigTimestamp xproto.Timestamp + Root xproto.Window + SubpixelOrder uint16 + // padding: 10 bytes +} + +// Reply blocks and returns the reply data for a SetScreenConfig request. +func (cook SetScreenConfigCookie) Reply() (*SetScreenConfigReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return setScreenConfigReply(buf), nil +} + +// setScreenConfigReply reads a byte slice into a SetScreenConfigReply value. +func setScreenConfigReply(buf []byte) *SetScreenConfigReply { + v := new(SetScreenConfigReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NewTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.ConfigTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.SubpixelOrder = xgb.Get16(buf[b:]) + b += 2 + + b += 10 // padding + + return v +} + +// Write request to wire for SetScreenConfig +// setScreenConfigRequest writes a SetScreenConfig request to a byte slice. +func setScreenConfigRequest(c *xgb.Conn, Window xproto.Window, Timestamp xproto.Timestamp, ConfigTimestamp xproto.Timestamp, SizeID uint16, Rotation uint16, Rate uint16) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(ConfigTimestamp)) + b += 4 + + xgb.Put16(buf[b:], SizeID) + b += 2 + + xgb.Put16(buf[b:], Rotation) + b += 2 + + xgb.Put16(buf[b:], Rate) + b += 2 + + b += 2 // padding + + return buf +} + +// SetScreenSizeCookie is a cookie used only for SetScreenSize requests. +type SetScreenSizeCookie struct { + *xgb.Cookie +} + +// SetScreenSize sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetScreenSize(c *xgb.Conn, Window xproto.Window, Width uint16, Height uint16, MmWidth uint32, MmHeight uint32) SetScreenSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetScreenSize' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setScreenSizeRequest(c, Window, Width, Height, MmWidth, MmHeight), cookie) + return SetScreenSizeCookie{cookie} +} + +// SetScreenSizeChecked sends a checked request. +// If an error occurs, it can be retrieved using SetScreenSizeCookie.Check() +func SetScreenSizeChecked(c *xgb.Conn, Window xproto.Window, Width uint16, Height uint16, MmWidth uint32, MmHeight uint32) SetScreenSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetScreenSize' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setScreenSizeRequest(c, Window, Width, Height, MmWidth, MmHeight), cookie) + return SetScreenSizeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetScreenSizeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetScreenSize +// setScreenSizeRequest writes a SetScreenSize request to a byte slice. +func setScreenSizeRequest(c *xgb.Conn, Window xproto.Window, Width uint16, Height uint16, MmWidth uint32, MmHeight uint32) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put32(buf[b:], MmWidth) + b += 4 + + xgb.Put32(buf[b:], MmHeight) + b += 4 + + return buf +} diff --git a/vend/xgb/record/record.go b/vend/xgb/record/record.go new file mode 100644 index 0000000..bf7c0ec --- /dev/null +++ b/vend/xgb/record/record.go @@ -0,0 +1,1204 @@ +// Package record is the X client API for the RECORD extension. +package record + +// This file is automatically generated from record.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the RECORD extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 6, "RECORD").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named RECORD could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["RECORD"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["RECORD"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["RECORD"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["RECORD"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["RECORD"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadContext is the error number for a BadBadContext. +const BadBadContext = 0 + +type BadContextError struct { + Sequence uint16 + NiceName string + InvalidRecord uint32 +} + +// BadContextErrorNew constructs a BadContextError value that implements xgb.Error from a byte slice. +func BadContextErrorNew(buf []byte) xgb.Error { + v := BadContextError{} + v.NiceName = "BadContext" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.InvalidRecord = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadContext error. +// This is mostly used internally. +func (err BadContextError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadContext error. If no bad value exists, 0 is returned. +func (err BadContextError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadContext error. + +func (err BadContextError) Error() string { + fieldVals := make([]string, 0, 1) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("InvalidRecord: %d", err.InvalidRecord)) + return "BadBadContext {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RECORD"][0] = BadContextErrorNew +} + +type ClientInfo struct { + ClientResource ClientSpec + NumRanges uint32 + Ranges []Range // size: xgb.Pad((int(NumRanges) * 24)) +} + +// ClientInfoRead reads a byte slice into a ClientInfo value. +func ClientInfoRead(buf []byte, v *ClientInfo) int { + b := 0 + + v.ClientResource = ClientSpec(xgb.Get32(buf[b:])) + b += 4 + + v.NumRanges = xgb.Get32(buf[b:]) + b += 4 + + v.Ranges = make([]Range, v.NumRanges) + b += RangeReadList(buf[b:], v.Ranges) + + return b +} + +// ClientInfoReadList reads a byte slice into a list of ClientInfo values. +func ClientInfoReadList(buf []byte, dest []ClientInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ClientInfo{} + b += ClientInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ClientInfo value to a byte slice. +func (v ClientInfo) Bytes() []byte { + buf := make([]byte, (8 + xgb.Pad((int(v.NumRanges) * 24)))) + b := 0 + + xgb.Put32(buf[b:], uint32(v.ClientResource)) + b += 4 + + xgb.Put32(buf[b:], v.NumRanges) + b += 4 + + b += RangeListBytes(buf[b:], v.Ranges) + + return buf[:b] +} + +// ClientInfoListBytes writes a list of ClientInfo values to a byte slice. +func ClientInfoListBytes(buf []byte, list []ClientInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ClientInfoListSize computes the size (bytes) of a list of ClientInfo values. +func ClientInfoListSize(list []ClientInfo) int { + size := 0 + for _, item := range list { + size += (8 + xgb.Pad((int(item.NumRanges) * 24))) + } + return size +} + +type ClientSpec uint32 + +type Context uint32 + +func NewContextId(c *xgb.Conn) (Context, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Context(id), nil +} + +const ( + CsCurrentClients = 1 + CsFutureClients = 2 + CsAllClients = 3 +) + +type ElementHeader byte + +type ExtRange struct { + Major Range8 + Minor Range16 +} + +// ExtRangeRead reads a byte slice into a ExtRange value. +func ExtRangeRead(buf []byte, v *ExtRange) int { + b := 0 + + v.Major = Range8{} + b += Range8Read(buf[b:], &v.Major) + + v.Minor = Range16{} + b += Range16Read(buf[b:], &v.Minor) + + return b +} + +// ExtRangeReadList reads a byte slice into a list of ExtRange values. +func ExtRangeReadList(buf []byte, dest []ExtRange) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ExtRange{} + b += ExtRangeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ExtRange value to a byte slice. +func (v ExtRange) Bytes() []byte { + buf := make([]byte, 6) + b := 0 + + { + structBytes := v.Major.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.Minor.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf[:b] +} + +// ExtRangeListBytes writes a list of ExtRange values to a byte slice. +func ExtRangeListBytes(buf []byte, list []ExtRange) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + HTypeFromServerTime = 1 + HTypeFromClientTime = 2 + HTypeFromClientSequence = 4 +) + +type Range struct { + CoreRequests Range8 + CoreReplies Range8 + ExtRequests ExtRange + ExtReplies ExtRange + DeliveredEvents Range8 + DeviceEvents Range8 + Errors Range8 + ClientStarted bool + ClientDied bool +} + +// RangeRead reads a byte slice into a Range value. +func RangeRead(buf []byte, v *Range) int { + b := 0 + + v.CoreRequests = Range8{} + b += Range8Read(buf[b:], &v.CoreRequests) + + v.CoreReplies = Range8{} + b += Range8Read(buf[b:], &v.CoreReplies) + + v.ExtRequests = ExtRange{} + b += ExtRangeRead(buf[b:], &v.ExtRequests) + + v.ExtReplies = ExtRange{} + b += ExtRangeRead(buf[b:], &v.ExtReplies) + + v.DeliveredEvents = Range8{} + b += Range8Read(buf[b:], &v.DeliveredEvents) + + v.DeviceEvents = Range8{} + b += Range8Read(buf[b:], &v.DeviceEvents) + + v.Errors = Range8{} + b += Range8Read(buf[b:], &v.Errors) + + if buf[b] == 1 { + v.ClientStarted = true + } else { + v.ClientStarted = false + } + b += 1 + + if buf[b] == 1 { + v.ClientDied = true + } else { + v.ClientDied = false + } + b += 1 + + return b +} + +// RangeReadList reads a byte slice into a list of Range values. +func RangeReadList(buf []byte, dest []Range) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Range{} + b += RangeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Range value to a byte slice. +func (v Range) Bytes() []byte { + buf := make([]byte, 24) + b := 0 + + { + structBytes := v.CoreRequests.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.CoreReplies.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.ExtRequests.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.ExtReplies.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.DeliveredEvents.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.DeviceEvents.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.Errors.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + if v.ClientStarted { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if v.ClientDied { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf[:b] +} + +// RangeListBytes writes a list of Range values to a byte slice. +func RangeListBytes(buf []byte, list []Range) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Range16 struct { + First uint16 + Last uint16 +} + +// Range16Read reads a byte slice into a Range16 value. +func Range16Read(buf []byte, v *Range16) int { + b := 0 + + v.First = xgb.Get16(buf[b:]) + b += 2 + + v.Last = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// Range16ReadList reads a byte slice into a list of Range16 values. +func Range16ReadList(buf []byte, dest []Range16) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Range16{} + b += Range16Read(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Range16 value to a byte slice. +func (v Range16) Bytes() []byte { + buf := make([]byte, 4) + b := 0 + + xgb.Put16(buf[b:], v.First) + b += 2 + + xgb.Put16(buf[b:], v.Last) + b += 2 + + return buf[:b] +} + +// Range16ListBytes writes a list of Range16 values to a byte slice. +func Range16ListBytes(buf []byte, list []Range16) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Range8 struct { + First byte + Last byte +} + +// Range8Read reads a byte slice into a Range8 value. +func Range8Read(buf []byte, v *Range8) int { + b := 0 + + v.First = buf[b] + b += 1 + + v.Last = buf[b] + b += 1 + + return b +} + +// Range8ReadList reads a byte slice into a list of Range8 values. +func Range8ReadList(buf []byte, dest []Range8) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Range8{} + b += Range8Read(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Range8 value to a byte slice. +func (v Range8) Bytes() []byte { + buf := make([]byte, 2) + b := 0 + + buf[b] = v.First + b += 1 + + buf[b] = v.Last + b += 1 + + return buf[:b] +} + +// Range8ListBytes writes a list of Range8 values to a byte slice. +func Range8ListBytes(buf []byte, list []Range8) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CreateContextCookie is a cookie used only for CreateContext requests. +type CreateContextCookie struct { + *xgb.Cookie +} + +// CreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateContext(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createContextRequest(c, Context, ElementHeader, NumClientSpecs, NumRanges, ClientSpecs, Ranges), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateContextCookie.Check() +func CreateContextChecked(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createContextRequest(c, Context, ElementHeader, NumClientSpecs, NumRanges, ClientSpecs, Ranges), cookie) + return CreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateContext +// createContextRequest writes a CreateContext request to a byte slice. +func createContextRequest(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) []byte { + size := xgb.Pad(((20 + xgb.Pad((int(NumClientSpecs) * 4))) + xgb.Pad((int(NumRanges) * 24)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + buf[b] = byte(ElementHeader) + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], NumClientSpecs) + b += 4 + + xgb.Put32(buf[b:], NumRanges) + b += 4 + + for i := 0; i < int(NumClientSpecs); i++ { + xgb.Put32(buf[b:], uint32(ClientSpecs[i])) + b += 4 + } + + b += RangeListBytes(buf[b:], Ranges) + + return buf +} + +// DisableContextCookie is a cookie used only for DisableContext requests. +type DisableContextCookie struct { + *xgb.Cookie +} + +// DisableContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DisableContext(c *xgb.Conn, Context Context) DisableContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'DisableContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(disableContextRequest(c, Context), cookie) + return DisableContextCookie{cookie} +} + +// DisableContextChecked sends a checked request. +// If an error occurs, it can be retrieved using DisableContextCookie.Check() +func DisableContextChecked(c *xgb.Conn, Context Context) DisableContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'DisableContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(disableContextRequest(c, Context), cookie) + return DisableContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DisableContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DisableContext +// disableContextRequest writes a DisableContext request to a byte slice. +func disableContextRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// EnableContextCookie is a cookie used only for EnableContext requests. +type EnableContextCookie struct { + *xgb.Cookie +} + +// EnableContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling EnableContextCookie.Reply() +func EnableContext(c *xgb.Conn, Context Context) EnableContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'EnableContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(enableContextRequest(c, Context), cookie) + return EnableContextCookie{cookie} +} + +// EnableContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func EnableContextUnchecked(c *xgb.Conn, Context Context) EnableContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'EnableContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(enableContextRequest(c, Context), cookie) + return EnableContextCookie{cookie} +} + +// EnableContextReply represents the data returned from a EnableContext request. +type EnableContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Category byte + ElementHeader ElementHeader + ClientSwapped bool + // padding: 2 bytes + XidBase uint32 + ServerTime uint32 + RecSequenceNum uint32 + // padding: 8 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a EnableContext request. +func (cook EnableContextCookie) Reply() (*EnableContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return enableContextReply(buf), nil +} + +// enableContextReply reads a byte slice into a EnableContextReply value. +func enableContextReply(buf []byte) *EnableContextReply { + v := new(EnableContextReply) + b := 1 // skip reply determinant + + v.Category = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ElementHeader = ElementHeader(buf[b]) + b += 1 + + if buf[b] == 1 { + v.ClientSwapped = true + } else { + v.ClientSwapped = false + } + b += 1 + + b += 2 // padding + + v.XidBase = xgb.Get32(buf[b:]) + b += 4 + + v.ServerTime = xgb.Get32(buf[b:]) + b += 4 + + v.RecSequenceNum = xgb.Get32(buf[b:]) + b += 4 + + b += 8 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for EnableContext +// enableContextRequest writes a EnableContext request to a byte slice. +func enableContextRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// FreeContextCookie is a cookie used only for FreeContext requests. +type FreeContextCookie struct { + *xgb.Cookie +} + +// FreeContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeContext(c *xgb.Conn, Context Context) FreeContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'FreeContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freeContextRequest(c, Context), cookie) + return FreeContextCookie{cookie} +} + +// FreeContextChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeContextCookie.Check() +func FreeContextChecked(c *xgb.Conn, Context Context) FreeContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'FreeContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freeContextRequest(c, Context), cookie) + return FreeContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeContext +// freeContextRequest writes a FreeContext request to a byte slice. +func freeContextRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// GetContextCookie is a cookie used only for GetContext requests. +type GetContextCookie struct { + *xgb.Cookie +} + +// GetContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetContextCookie.Reply() +func GetContext(c *xgb.Conn, Context Context) GetContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'GetContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getContextRequest(c, Context), cookie) + return GetContextCookie{cookie} +} + +// GetContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetContextUnchecked(c *xgb.Conn, Context Context) GetContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'GetContext' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getContextRequest(c, Context), cookie) + return GetContextCookie{cookie} +} + +// GetContextReply represents the data returned from a GetContext request. +type GetContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Enabled bool + ElementHeader ElementHeader + // padding: 3 bytes + NumInterceptedClients uint32 + // padding: 16 bytes + InterceptedClients []ClientInfo // size: ClientInfoListSize(InterceptedClients) +} + +// Reply blocks and returns the reply data for a GetContext request. +func (cook GetContextCookie) Reply() (*GetContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getContextReply(buf), nil +} + +// getContextReply reads a byte slice into a GetContextReply value. +func getContextReply(buf []byte) *GetContextReply { + v := new(GetContextReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.Enabled = true + } else { + v.Enabled = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ElementHeader = ElementHeader(buf[b]) + b += 1 + + b += 3 // padding + + v.NumInterceptedClients = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + v.InterceptedClients = make([]ClientInfo, v.NumInterceptedClients) + b += ClientInfoReadList(buf[b:], v.InterceptedClients) + + return v +} + +// Write request to wire for GetContext +// getContextRequest writes a GetContext request to a byte slice. +func getContextRequest(c *xgb.Conn, Context Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, MajorVersion uint16, MinorVersion uint16) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, MajorVersion uint16, MinorVersion uint16) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint16 + MinorVersion uint16 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, MajorVersion uint16, MinorVersion uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], MajorVersion) + b += 2 + + xgb.Put16(buf[b:], MinorVersion) + b += 2 + + return buf +} + +// RegisterClientsCookie is a cookie used only for RegisterClients requests. +type RegisterClientsCookie struct { + *xgb.Cookie +} + +// RegisterClients sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RegisterClients(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) RegisterClientsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'RegisterClients' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(registerClientsRequest(c, Context, ElementHeader, NumClientSpecs, NumRanges, ClientSpecs, Ranges), cookie) + return RegisterClientsCookie{cookie} +} + +// RegisterClientsChecked sends a checked request. +// If an error occurs, it can be retrieved using RegisterClientsCookie.Check() +func RegisterClientsChecked(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) RegisterClientsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'RegisterClients' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(registerClientsRequest(c, Context, ElementHeader, NumClientSpecs, NumRanges, ClientSpecs, Ranges), cookie) + return RegisterClientsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RegisterClientsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RegisterClients +// registerClientsRequest writes a RegisterClients request to a byte slice. +func registerClientsRequest(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) []byte { + size := xgb.Pad(((20 + xgb.Pad((int(NumClientSpecs) * 4))) + xgb.Pad((int(NumRanges) * 24)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + buf[b] = byte(ElementHeader) + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], NumClientSpecs) + b += 4 + + xgb.Put32(buf[b:], NumRanges) + b += 4 + + for i := 0; i < int(NumClientSpecs); i++ { + xgb.Put32(buf[b:], uint32(ClientSpecs[i])) + b += 4 + } + + b += RangeListBytes(buf[b:], Ranges) + + return buf +} + +// UnregisterClientsCookie is a cookie used only for UnregisterClients requests. +type UnregisterClientsCookie struct { + *xgb.Cookie +} + +// UnregisterClients sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnregisterClients(c *xgb.Conn, Context Context, NumClientSpecs uint32, ClientSpecs []ClientSpec) UnregisterClientsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'UnregisterClients' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(unregisterClientsRequest(c, Context, NumClientSpecs, ClientSpecs), cookie) + return UnregisterClientsCookie{cookie} +} + +// UnregisterClientsChecked sends a checked request. +// If an error occurs, it can be retrieved using UnregisterClientsCookie.Check() +func UnregisterClientsChecked(c *xgb.Conn, Context Context, NumClientSpecs uint32, ClientSpecs []ClientSpec) UnregisterClientsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RECORD"]; !ok { + panic("Cannot issue request 'UnregisterClients' using the uninitialized extension 'RECORD'. record.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(unregisterClientsRequest(c, Context, NumClientSpecs, ClientSpecs), cookie) + return UnregisterClientsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnregisterClientsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnregisterClients +// unregisterClientsRequest writes a UnregisterClients request to a byte slice. +func unregisterClientsRequest(c *xgb.Conn, Context Context, NumClientSpecs uint32, ClientSpecs []ClientSpec) []byte { + size := xgb.Pad((12 + xgb.Pad((int(NumClientSpecs) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RECORD"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], NumClientSpecs) + b += 4 + + for i := 0; i < int(NumClientSpecs); i++ { + xgb.Put32(buf[b:], uint32(ClientSpecs[i])) + b += 4 + } + + return buf +} diff --git a/vend/xgb/render/render.go b/vend/xgb/render/render.go new file mode 100644 index 0000000..839a05d --- /dev/null +++ b/vend/xgb/render/render.go @@ -0,0 +1,4029 @@ +// Package render is the X client API for the RENDER extension. +package render + +// This file is automatically generated from render.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the RENDER extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 6, "RENDER").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named RENDER could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["RENDER"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["RENDER"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["RENDER"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["RENDER"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["RENDER"] = make(map[int]xgb.NewErrorFun) +} + +type Animcursorelt struct { + Cursor xproto.Cursor + Delay uint32 +} + +// AnimcursoreltRead reads a byte slice into a Animcursorelt value. +func AnimcursoreltRead(buf []byte, v *Animcursorelt) int { + b := 0 + + v.Cursor = xproto.Cursor(xgb.Get32(buf[b:])) + b += 4 + + v.Delay = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// AnimcursoreltReadList reads a byte slice into a list of Animcursorelt values. +func AnimcursoreltReadList(buf []byte, dest []Animcursorelt) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Animcursorelt{} + b += AnimcursoreltRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Animcursorelt value to a byte slice. +func (v Animcursorelt) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Cursor)) + b += 4 + + xgb.Put32(buf[b:], v.Delay) + b += 4 + + return buf[:b] +} + +// AnimcursoreltListBytes writes a list of Animcursorelt values to a byte slice. +func AnimcursoreltListBytes(buf []byte, list []Animcursorelt) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Color struct { + Red uint16 + Green uint16 + Blue uint16 + Alpha uint16 +} + +// ColorRead reads a byte slice into a Color value. +func ColorRead(buf []byte, v *Color) int { + b := 0 + + v.Red = xgb.Get16(buf[b:]) + b += 2 + + v.Green = xgb.Get16(buf[b:]) + b += 2 + + v.Blue = xgb.Get16(buf[b:]) + b += 2 + + v.Alpha = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// ColorReadList reads a byte slice into a list of Color values. +func ColorReadList(buf []byte, dest []Color) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Color{} + b += ColorRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Color value to a byte slice. +func (v Color) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], v.Red) + b += 2 + + xgb.Put16(buf[b:], v.Green) + b += 2 + + xgb.Put16(buf[b:], v.Blue) + b += 2 + + xgb.Put16(buf[b:], v.Alpha) + b += 2 + + return buf[:b] +} + +// ColorListBytes writes a list of Color values to a byte slice. +func ColorListBytes(buf []byte, list []Color) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + CpRepeat = 1 + CpAlphaMap = 2 + CpAlphaXOrigin = 4 + CpAlphaYOrigin = 8 + CpClipXOrigin = 16 + CpClipYOrigin = 32 + CpClipMask = 64 + CpGraphicsExposure = 128 + CpSubwindowMode = 256 + CpPolyEdge = 512 + CpPolyMode = 1024 + CpDither = 2048 + CpComponentAlpha = 4096 +) + +type Directformat struct { + RedShift uint16 + RedMask uint16 + GreenShift uint16 + GreenMask uint16 + BlueShift uint16 + BlueMask uint16 + AlphaShift uint16 + AlphaMask uint16 +} + +// DirectformatRead reads a byte slice into a Directformat value. +func DirectformatRead(buf []byte, v *Directformat) int { + b := 0 + + v.RedShift = xgb.Get16(buf[b:]) + b += 2 + + v.RedMask = xgb.Get16(buf[b:]) + b += 2 + + v.GreenShift = xgb.Get16(buf[b:]) + b += 2 + + v.GreenMask = xgb.Get16(buf[b:]) + b += 2 + + v.BlueShift = xgb.Get16(buf[b:]) + b += 2 + + v.BlueMask = xgb.Get16(buf[b:]) + b += 2 + + v.AlphaShift = xgb.Get16(buf[b:]) + b += 2 + + v.AlphaMask = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// DirectformatReadList reads a byte slice into a list of Directformat values. +func DirectformatReadList(buf []byte, dest []Directformat) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Directformat{} + b += DirectformatRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Directformat value to a byte slice. +func (v Directformat) Bytes() []byte { + buf := make([]byte, 16) + b := 0 + + xgb.Put16(buf[b:], v.RedShift) + b += 2 + + xgb.Put16(buf[b:], v.RedMask) + b += 2 + + xgb.Put16(buf[b:], v.GreenShift) + b += 2 + + xgb.Put16(buf[b:], v.GreenMask) + b += 2 + + xgb.Put16(buf[b:], v.BlueShift) + b += 2 + + xgb.Put16(buf[b:], v.BlueMask) + b += 2 + + xgb.Put16(buf[b:], v.AlphaShift) + b += 2 + + xgb.Put16(buf[b:], v.AlphaMask) + b += 2 + + return buf[:b] +} + +// DirectformatListBytes writes a list of Directformat values to a byte slice. +func DirectformatListBytes(buf []byte, list []Directformat) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Fixed int32 + +type Glyph uint32 + +// BadGlyph is the error number for a BadGlyph. +const BadGlyph = 4 + +type GlyphError struct { + Sequence uint16 + NiceName string +} + +// GlyphErrorNew constructs a GlyphError value that implements xgb.Error from a byte slice. +func GlyphErrorNew(buf []byte) xgb.Error { + v := GlyphError{} + v.NiceName = "Glyph" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadGlyph error. +// This is mostly used internally. +func (err GlyphError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadGlyph error. If no bad value exists, 0 is returned. +func (err GlyphError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadGlyph error. + +func (err GlyphError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadGlyph {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RENDER"][4] = GlyphErrorNew +} + +// BadGlyphSet is the error number for a BadGlyphSet. +const BadGlyphSet = 3 + +type GlyphSetError struct { + Sequence uint16 + NiceName string +} + +// GlyphSetErrorNew constructs a GlyphSetError value that implements xgb.Error from a byte slice. +func GlyphSetErrorNew(buf []byte) xgb.Error { + v := GlyphSetError{} + v.NiceName = "GlyphSet" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadGlyphSet error. +// This is mostly used internally. +func (err GlyphSetError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadGlyphSet error. If no bad value exists, 0 is returned. +func (err GlyphSetError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadGlyphSet error. + +func (err GlyphSetError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadGlyphSet {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RENDER"][3] = GlyphSetErrorNew +} + +type Glyphinfo struct { + Width uint16 + Height uint16 + X int16 + Y int16 + XOff int16 + YOff int16 +} + +// GlyphinfoRead reads a byte slice into a Glyphinfo value. +func GlyphinfoRead(buf []byte, v *Glyphinfo) int { + b := 0 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.XOff = int16(xgb.Get16(buf[b:])) + b += 2 + + v.YOff = int16(xgb.Get16(buf[b:])) + b += 2 + + return b +} + +// GlyphinfoReadList reads a byte slice into a list of Glyphinfo values. +func GlyphinfoReadList(buf []byte, dest []Glyphinfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Glyphinfo{} + b += GlyphinfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Glyphinfo value to a byte slice. +func (v Glyphinfo) Bytes() []byte { + buf := make([]byte, 12) + b := 0 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.XOff)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.YOff)) + b += 2 + + return buf[:b] +} + +// GlyphinfoListBytes writes a list of Glyphinfo values to a byte slice. +func GlyphinfoListBytes(buf []byte, list []Glyphinfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Glyphset uint32 + +func NewGlyphsetId(c *xgb.Conn) (Glyphset, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Glyphset(id), nil +} + +type Indexvalue struct { + Pixel uint32 + Red uint16 + Green uint16 + Blue uint16 + Alpha uint16 +} + +// IndexvalueRead reads a byte slice into a Indexvalue value. +func IndexvalueRead(buf []byte, v *Indexvalue) int { + b := 0 + + v.Pixel = xgb.Get32(buf[b:]) + b += 4 + + v.Red = xgb.Get16(buf[b:]) + b += 2 + + v.Green = xgb.Get16(buf[b:]) + b += 2 + + v.Blue = xgb.Get16(buf[b:]) + b += 2 + + v.Alpha = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// IndexvalueReadList reads a byte slice into a list of Indexvalue values. +func IndexvalueReadList(buf []byte, dest []Indexvalue) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Indexvalue{} + b += IndexvalueRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Indexvalue value to a byte slice. +func (v Indexvalue) Bytes() []byte { + buf := make([]byte, 12) + b := 0 + + xgb.Put32(buf[b:], v.Pixel) + b += 4 + + xgb.Put16(buf[b:], v.Red) + b += 2 + + xgb.Put16(buf[b:], v.Green) + b += 2 + + xgb.Put16(buf[b:], v.Blue) + b += 2 + + xgb.Put16(buf[b:], v.Alpha) + b += 2 + + return buf[:b] +} + +// IndexvalueListBytes writes a list of Indexvalue values to a byte slice. +func IndexvalueListBytes(buf []byte, list []Indexvalue) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Linefix struct { + P1 Pointfix + P2 Pointfix +} + +// LinefixRead reads a byte slice into a Linefix value. +func LinefixRead(buf []byte, v *Linefix) int { + b := 0 + + v.P1 = Pointfix{} + b += PointfixRead(buf[b:], &v.P1) + + v.P2 = Pointfix{} + b += PointfixRead(buf[b:], &v.P2) + + return b +} + +// LinefixReadList reads a byte slice into a list of Linefix values. +func LinefixReadList(buf []byte, dest []Linefix) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Linefix{} + b += LinefixRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Linefix value to a byte slice. +func (v Linefix) Bytes() []byte { + buf := make([]byte, 16) + b := 0 + + { + structBytes := v.P1.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.P2.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf[:b] +} + +// LinefixListBytes writes a list of Linefix values to a byte slice. +func LinefixListBytes(buf []byte, list []Linefix) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// BadPictFormat is the error number for a BadPictFormat. +const BadPictFormat = 0 + +type PictFormatError struct { + Sequence uint16 + NiceName string +} + +// PictFormatErrorNew constructs a PictFormatError value that implements xgb.Error from a byte slice. +func PictFormatErrorNew(buf []byte) xgb.Error { + v := PictFormatError{} + v.NiceName = "PictFormat" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadPictFormat error. +// This is mostly used internally. +func (err PictFormatError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadPictFormat error. If no bad value exists, 0 is returned. +func (err PictFormatError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadPictFormat error. + +func (err PictFormatError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadPictFormat {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RENDER"][0] = PictFormatErrorNew +} + +const ( + PictOpClear = 0 + PictOpSrc = 1 + PictOpDst = 2 + PictOpOver = 3 + PictOpOverReverse = 4 + PictOpIn = 5 + PictOpInReverse = 6 + PictOpOut = 7 + PictOpOutReverse = 8 + PictOpAtop = 9 + PictOpAtopReverse = 10 + PictOpXor = 11 + PictOpAdd = 12 + PictOpSaturate = 13 + PictOpDisjointClear = 16 + PictOpDisjointSrc = 17 + PictOpDisjointDst = 18 + PictOpDisjointOver = 19 + PictOpDisjointOverReverse = 20 + PictOpDisjointIn = 21 + PictOpDisjointInReverse = 22 + PictOpDisjointOut = 23 + PictOpDisjointOutReverse = 24 + PictOpDisjointAtop = 25 + PictOpDisjointAtopReverse = 26 + PictOpDisjointXor = 27 + PictOpConjointClear = 32 + PictOpConjointSrc = 33 + PictOpConjointDst = 34 + PictOpConjointOver = 35 + PictOpConjointOverReverse = 36 + PictOpConjointIn = 37 + PictOpConjointInReverse = 38 + PictOpConjointOut = 39 + PictOpConjointOutReverse = 40 + PictOpConjointAtop = 41 + PictOpConjointAtopReverse = 42 + PictOpConjointXor = 43 + PictOpMultiply = 48 + PictOpScreen = 49 + PictOpOverlay = 50 + PictOpDarken = 51 + PictOpLighten = 52 + PictOpColorDodge = 53 + PictOpColorBurn = 54 + PictOpHardLight = 55 + PictOpSoftLight = 56 + PictOpDifference = 57 + PictOpExclusion = 58 + PictOpHSLHue = 59 + PictOpHSLSaturation = 60 + PictOpHSLColor = 61 + PictOpHSLLuminosity = 62 +) + +// BadPictOp is the error number for a BadPictOp. +const BadPictOp = 2 + +type PictOpError struct { + Sequence uint16 + NiceName string +} + +// PictOpErrorNew constructs a PictOpError value that implements xgb.Error from a byte slice. +func PictOpErrorNew(buf []byte) xgb.Error { + v := PictOpError{} + v.NiceName = "PictOp" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadPictOp error. +// This is mostly used internally. +func (err PictOpError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadPictOp error. If no bad value exists, 0 is returned. +func (err PictOpError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadPictOp error. + +func (err PictOpError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadPictOp {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RENDER"][2] = PictOpErrorNew +} + +const ( + PictTypeIndexed = 0 + PictTypeDirect = 1 +) + +type Pictdepth struct { + Depth byte + // padding: 1 bytes + NumVisuals uint16 + // padding: 4 bytes + Visuals []Pictvisual // size: xgb.Pad((int(NumVisuals) * 8)) +} + +// PictdepthRead reads a byte slice into a Pictdepth value. +func PictdepthRead(buf []byte, v *Pictdepth) int { + b := 0 + + v.Depth = buf[b] + b += 1 + + b += 1 // padding + + v.NumVisuals = xgb.Get16(buf[b:]) + b += 2 + + b += 4 // padding + + v.Visuals = make([]Pictvisual, v.NumVisuals) + b += PictvisualReadList(buf[b:], v.Visuals) + + return b +} + +// PictdepthReadList reads a byte slice into a list of Pictdepth values. +func PictdepthReadList(buf []byte, dest []Pictdepth) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Pictdepth{} + b += PictdepthRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Pictdepth value to a byte slice. +func (v Pictdepth) Bytes() []byte { + buf := make([]byte, (8 + xgb.Pad((int(v.NumVisuals) * 8)))) + b := 0 + + buf[b] = v.Depth + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], v.NumVisuals) + b += 2 + + b += 4 // padding + + b += PictvisualListBytes(buf[b:], v.Visuals) + + return buf[:b] +} + +// PictdepthListBytes writes a list of Pictdepth values to a byte slice. +func PictdepthListBytes(buf []byte, list []Pictdepth) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// PictdepthListSize computes the size (bytes) of a list of Pictdepth values. +func PictdepthListSize(list []Pictdepth) int { + size := 0 + for _, item := range list { + size += (8 + xgb.Pad((int(item.NumVisuals) * 8))) + } + return size +} + +type Pictformat uint32 + +func NewPictformatId(c *xgb.Conn) (Pictformat, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Pictformat(id), nil +} + +type Pictforminfo struct { + Id Pictformat + Type byte + Depth byte + // padding: 2 bytes + Direct Directformat + Colormap xproto.Colormap +} + +// PictforminfoRead reads a byte slice into a Pictforminfo value. +func PictforminfoRead(buf []byte, v *Pictforminfo) int { + b := 0 + + v.Id = Pictformat(xgb.Get32(buf[b:])) + b += 4 + + v.Type = buf[b] + b += 1 + + v.Depth = buf[b] + b += 1 + + b += 2 // padding + + v.Direct = Directformat{} + b += DirectformatRead(buf[b:], &v.Direct) + + v.Colormap = xproto.Colormap(xgb.Get32(buf[b:])) + b += 4 + + return b +} + +// PictforminfoReadList reads a byte slice into a list of Pictforminfo values. +func PictforminfoReadList(buf []byte, dest []Pictforminfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Pictforminfo{} + b += PictforminfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Pictforminfo value to a byte slice. +func (v Pictforminfo) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Id)) + b += 4 + + buf[b] = v.Type + b += 1 + + buf[b] = v.Depth + b += 1 + + b += 2 // padding + + { + structBytes := v.Direct.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], uint32(v.Colormap)) + b += 4 + + return buf[:b] +} + +// PictforminfoListBytes writes a list of Pictforminfo values to a byte slice. +func PictforminfoListBytes(buf []byte, list []Pictforminfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Pictscreen struct { + NumDepths uint32 + Fallback Pictformat + Depths []Pictdepth // size: PictdepthListSize(Depths) +} + +// PictscreenRead reads a byte slice into a Pictscreen value. +func PictscreenRead(buf []byte, v *Pictscreen) int { + b := 0 + + v.NumDepths = xgb.Get32(buf[b:]) + b += 4 + + v.Fallback = Pictformat(xgb.Get32(buf[b:])) + b += 4 + + v.Depths = make([]Pictdepth, v.NumDepths) + b += PictdepthReadList(buf[b:], v.Depths) + + return b +} + +// PictscreenReadList reads a byte slice into a list of Pictscreen values. +func PictscreenReadList(buf []byte, dest []Pictscreen) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Pictscreen{} + b += PictscreenRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Pictscreen value to a byte slice. +func (v Pictscreen) Bytes() []byte { + buf := make([]byte, (8 + PictdepthListSize(v.Depths))) + b := 0 + + xgb.Put32(buf[b:], v.NumDepths) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Fallback)) + b += 4 + + b += PictdepthListBytes(buf[b:], v.Depths) + + return buf[:b] +} + +// PictscreenListBytes writes a list of Pictscreen values to a byte slice. +func PictscreenListBytes(buf []byte, list []Pictscreen) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// PictscreenListSize computes the size (bytes) of a list of Pictscreen values. +func PictscreenListSize(list []Pictscreen) int { + size := 0 + for _, item := range list { + size += (8 + PictdepthListSize(item.Depths)) + } + return size +} + +type Picture uint32 + +func NewPictureId(c *xgb.Conn) (Picture, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Picture(id), nil +} + +// BadPicture is the error number for a BadPicture. +const BadPicture = 1 + +type PictureError struct { + Sequence uint16 + NiceName string +} + +// PictureErrorNew constructs a PictureError value that implements xgb.Error from a byte slice. +func PictureErrorNew(buf []byte) xgb.Error { + v := PictureError{} + v.NiceName = "Picture" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadPicture error. +// This is mostly used internally. +func (err PictureError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadPicture error. If no bad value exists, 0 is returned. +func (err PictureError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadPicture error. + +func (err PictureError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadPicture {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RENDER"][1] = PictureErrorNew +} + +const ( + PictureNone = 0 +) + +type Pictvisual struct { + Visual xproto.Visualid + Format Pictformat +} + +// PictvisualRead reads a byte slice into a Pictvisual value. +func PictvisualRead(buf []byte, v *Pictvisual) int { + b := 0 + + v.Visual = xproto.Visualid(xgb.Get32(buf[b:])) + b += 4 + + v.Format = Pictformat(xgb.Get32(buf[b:])) + b += 4 + + return b +} + +// PictvisualReadList reads a byte slice into a list of Pictvisual values. +func PictvisualReadList(buf []byte, dest []Pictvisual) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Pictvisual{} + b += PictvisualRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Pictvisual value to a byte slice. +func (v Pictvisual) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Visual)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Format)) + b += 4 + + return buf[:b] +} + +// PictvisualListBytes writes a list of Pictvisual values to a byte slice. +func PictvisualListBytes(buf []byte, list []Pictvisual) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Pointfix struct { + X Fixed + Y Fixed +} + +// PointfixRead reads a byte slice into a Pointfix value. +func PointfixRead(buf []byte, v *Pointfix) int { + b := 0 + + v.X = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Y = Fixed(xgb.Get32(buf[b:])) + b += 4 + + return b +} + +// PointfixReadList reads a byte slice into a list of Pointfix values. +func PointfixReadList(buf []byte, dest []Pointfix) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Pointfix{} + b += PointfixRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Pointfix value to a byte slice. +func (v Pointfix) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.X)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Y)) + b += 4 + + return buf[:b] +} + +// PointfixListBytes writes a list of Pointfix values to a byte slice. +func PointfixListBytes(buf []byte, list []Pointfix) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + PolyEdgeSharp = 0 + PolyEdgeSmooth = 1 +) + +const ( + PolyModePrecise = 0 + PolyModeImprecise = 1 +) + +const ( + RepeatNone = 0 + RepeatNormal = 1 + RepeatPad = 2 + RepeatReflect = 3 +) + +type Spanfix struct { + L Fixed + R Fixed + Y Fixed +} + +// SpanfixRead reads a byte slice into a Spanfix value. +func SpanfixRead(buf []byte, v *Spanfix) int { + b := 0 + + v.L = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.R = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Y = Fixed(xgb.Get32(buf[b:])) + b += 4 + + return b +} + +// SpanfixReadList reads a byte slice into a list of Spanfix values. +func SpanfixReadList(buf []byte, dest []Spanfix) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Spanfix{} + b += SpanfixRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Spanfix value to a byte slice. +func (v Spanfix) Bytes() []byte { + buf := make([]byte, 12) + b := 0 + + xgb.Put32(buf[b:], uint32(v.L)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.R)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Y)) + b += 4 + + return buf[:b] +} + +// SpanfixListBytes writes a list of Spanfix values to a byte slice. +func SpanfixListBytes(buf []byte, list []Spanfix) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + SubPixelUnknown = 0 + SubPixelHorizontalRGB = 1 + SubPixelHorizontalBGR = 2 + SubPixelVerticalRGB = 3 + SubPixelVerticalBGR = 4 + SubPixelNone = 5 +) + +type Transform struct { + Matrix11 Fixed + Matrix12 Fixed + Matrix13 Fixed + Matrix21 Fixed + Matrix22 Fixed + Matrix23 Fixed + Matrix31 Fixed + Matrix32 Fixed + Matrix33 Fixed +} + +// TransformRead reads a byte slice into a Transform value. +func TransformRead(buf []byte, v *Transform) int { + b := 0 + + v.Matrix11 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix12 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix13 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix21 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix22 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix23 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix31 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix32 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Matrix33 = Fixed(xgb.Get32(buf[b:])) + b += 4 + + return b +} + +// TransformReadList reads a byte slice into a list of Transform values. +func TransformReadList(buf []byte, dest []Transform) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Transform{} + b += TransformRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Transform value to a byte slice. +func (v Transform) Bytes() []byte { + buf := make([]byte, 36) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Matrix11)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix12)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix13)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix21)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix22)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix23)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix31)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix32)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Matrix33)) + b += 4 + + return buf[:b] +} + +// TransformListBytes writes a list of Transform values to a byte slice. +func TransformListBytes(buf []byte, list []Transform) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Trap struct { + Top Spanfix + Bot Spanfix +} + +// TrapRead reads a byte slice into a Trap value. +func TrapRead(buf []byte, v *Trap) int { + b := 0 + + v.Top = Spanfix{} + b += SpanfixRead(buf[b:], &v.Top) + + v.Bot = Spanfix{} + b += SpanfixRead(buf[b:], &v.Bot) + + return b +} + +// TrapReadList reads a byte slice into a list of Trap values. +func TrapReadList(buf []byte, dest []Trap) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Trap{} + b += TrapRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Trap value to a byte slice. +func (v Trap) Bytes() []byte { + buf := make([]byte, 24) + b := 0 + + { + structBytes := v.Top.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.Bot.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf[:b] +} + +// TrapListBytes writes a list of Trap values to a byte slice. +func TrapListBytes(buf []byte, list []Trap) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Trapezoid struct { + Top Fixed + Bottom Fixed + Left Linefix + Right Linefix +} + +// TrapezoidRead reads a byte slice into a Trapezoid value. +func TrapezoidRead(buf []byte, v *Trapezoid) int { + b := 0 + + v.Top = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Bottom = Fixed(xgb.Get32(buf[b:])) + b += 4 + + v.Left = Linefix{} + b += LinefixRead(buf[b:], &v.Left) + + v.Right = Linefix{} + b += LinefixRead(buf[b:], &v.Right) + + return b +} + +// TrapezoidReadList reads a byte slice into a list of Trapezoid values. +func TrapezoidReadList(buf []byte, dest []Trapezoid) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Trapezoid{} + b += TrapezoidRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Trapezoid value to a byte slice. +func (v Trapezoid) Bytes() []byte { + buf := make([]byte, 40) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Top)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Bottom)) + b += 4 + + { + structBytes := v.Left.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.Right.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf[:b] +} + +// TrapezoidListBytes writes a list of Trapezoid values to a byte slice. +func TrapezoidListBytes(buf []byte, list []Trapezoid) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Triangle struct { + P1 Pointfix + P2 Pointfix + P3 Pointfix +} + +// TriangleRead reads a byte slice into a Triangle value. +func TriangleRead(buf []byte, v *Triangle) int { + b := 0 + + v.P1 = Pointfix{} + b += PointfixRead(buf[b:], &v.P1) + + v.P2 = Pointfix{} + b += PointfixRead(buf[b:], &v.P2) + + v.P3 = Pointfix{} + b += PointfixRead(buf[b:], &v.P3) + + return b +} + +// TriangleReadList reads a byte slice into a list of Triangle values. +func TriangleReadList(buf []byte, dest []Triangle) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Triangle{} + b += TriangleRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Triangle value to a byte slice. +func (v Triangle) Bytes() []byte { + buf := make([]byte, 24) + b := 0 + + { + structBytes := v.P1.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.P2.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := v.P3.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf[:b] +} + +// TriangleListBytes writes a list of Triangle values to a byte slice. +func TriangleListBytes(buf []byte, list []Triangle) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AddGlyphsCookie is a cookie used only for AddGlyphs requests. +type AddGlyphsCookie struct { + *xgb.Cookie +} + +// AddGlyphs sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AddGlyphs(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) AddGlyphsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'AddGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(addGlyphsRequest(c, Glyphset, GlyphsLen, Glyphids, Glyphs, Data), cookie) + return AddGlyphsCookie{cookie} +} + +// AddGlyphsChecked sends a checked request. +// If an error occurs, it can be retrieved using AddGlyphsCookie.Check() +func AddGlyphsChecked(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) AddGlyphsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'AddGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(addGlyphsRequest(c, Glyphset, GlyphsLen, Glyphids, Glyphs, Data), cookie) + return AddGlyphsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AddGlyphsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for AddGlyphs +// addGlyphsRequest writes a AddGlyphs request to a byte slice. +func addGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) []byte { + size := xgb.Pad((((12 + xgb.Pad((int(GlyphsLen) * 4))) + xgb.Pad((int(GlyphsLen) * 12))) + xgb.Pad((len(Data) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Glyphset)) + b += 4 + + xgb.Put32(buf[b:], GlyphsLen) + b += 4 + + for i := 0; i < int(GlyphsLen); i++ { + xgb.Put32(buf[b:], Glyphids[i]) + b += 4 + } + + b += GlyphinfoListBytes(buf[b:], Glyphs) + + copy(buf[b:], Data[:len(Data)]) + b += int(len(Data)) + + return buf +} + +// AddTrapsCookie is a cookie used only for AddTraps requests. +type AddTrapsCookie struct { + *xgb.Cookie +} + +// AddTraps sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AddTraps(c *xgb.Conn, Picture Picture, XOff int16, YOff int16, Traps []Trap) AddTrapsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'AddTraps' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(addTrapsRequest(c, Picture, XOff, YOff, Traps), cookie) + return AddTrapsCookie{cookie} +} + +// AddTrapsChecked sends a checked request. +// If an error occurs, it can be retrieved using AddTrapsCookie.Check() +func AddTrapsChecked(c *xgb.Conn, Picture Picture, XOff int16, YOff int16, Traps []Trap) AddTrapsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'AddTraps' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(addTrapsRequest(c, Picture, XOff, YOff, Traps), cookie) + return AddTrapsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AddTrapsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for AddTraps +// addTrapsRequest writes a AddTraps request to a byte slice. +func addTrapsRequest(c *xgb.Conn, Picture Picture, XOff int16, YOff int16, Traps []Trap) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Traps) * 24)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 32 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOff)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOff)) + b += 2 + + b += TrapListBytes(buf[b:], Traps) + + return buf +} + +// ChangePictureCookie is a cookie used only for ChangePicture requests. +type ChangePictureCookie struct { + *xgb.Cookie +} + +// ChangePicture sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangePicture(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) ChangePictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'ChangePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changePictureRequest(c, Picture, ValueMask, ValueList), cookie) + return ChangePictureCookie{cookie} +} + +// ChangePictureChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangePictureCookie.Check() +func ChangePictureChecked(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) ChangePictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'ChangePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changePictureRequest(c, Picture, ValueMask, ValueList), cookie) + return ChangePictureCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangePictureCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangePicture +// changePictureRequest writes a ChangePicture request to a byte slice. +func changePictureRequest(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// CompositeCookie is a cookie used only for Composite requests. +type CompositeCookie struct { + *xgb.Cookie +} + +// Composite sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Composite(c *xgb.Conn, Op byte, Src Picture, Mask Picture, Dst Picture, SrcX int16, SrcY int16, MaskX int16, MaskY int16, DstX int16, DstY int16, Width uint16, Height uint16) CompositeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'Composite' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(compositeRequest(c, Op, Src, Mask, Dst, SrcX, SrcY, MaskX, MaskY, DstX, DstY, Width, Height), cookie) + return CompositeCookie{cookie} +} + +// CompositeChecked sends a checked request. +// If an error occurs, it can be retrieved using CompositeCookie.Check() +func CompositeChecked(c *xgb.Conn, Op byte, Src Picture, Mask Picture, Dst Picture, SrcX int16, SrcY int16, MaskX int16, MaskY int16, DstX int16, DstY int16, Width uint16, Height uint16) CompositeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'Composite' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(compositeRequest(c, Op, Src, Mask, Dst, SrcX, SrcY, MaskX, MaskY, DstX, DstY, Width, Height), cookie) + return CompositeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CompositeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Composite +// compositeRequest writes a Composite request to a byte slice. +func compositeRequest(c *xgb.Conn, Op byte, Src Picture, Mask Picture, Dst Picture, SrcX int16, SrcY int16, MaskX int16, MaskY int16, DstX int16, DstY int16, Width uint16, Height uint16) []byte { + size := 36 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Mask)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + xgb.Put16(buf[b:], uint16(MaskX)) + b += 2 + + xgb.Put16(buf[b:], uint16(MaskY)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstY)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// CompositeGlyphs16Cookie is a cookie used only for CompositeGlyphs16 requests. +type CompositeGlyphs16Cookie struct { + *xgb.Cookie +} + +// CompositeGlyphs16 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CompositeGlyphs16(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs16Cookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CompositeGlyphs16' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(compositeGlyphs16Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie) + return CompositeGlyphs16Cookie{cookie} +} + +// CompositeGlyphs16Checked sends a checked request. +// If an error occurs, it can be retrieved using CompositeGlyphs16Cookie.Check() +func CompositeGlyphs16Checked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs16Cookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CompositeGlyphs16' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(compositeGlyphs16Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie) + return CompositeGlyphs16Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CompositeGlyphs16Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CompositeGlyphs16 +// compositeGlyphs16Request writes a CompositeGlyphs16 request to a byte slice. +func compositeGlyphs16Request(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) []byte { + size := xgb.Pad((28 + xgb.Pad((len(Glyphcmds) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 24 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put32(buf[b:], uint32(Glyphset)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + copy(buf[b:], Glyphcmds[:len(Glyphcmds)]) + b += int(len(Glyphcmds)) + + return buf +} + +// CompositeGlyphs32Cookie is a cookie used only for CompositeGlyphs32 requests. +type CompositeGlyphs32Cookie struct { + *xgb.Cookie +} + +// CompositeGlyphs32 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CompositeGlyphs32(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs32Cookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CompositeGlyphs32' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(compositeGlyphs32Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie) + return CompositeGlyphs32Cookie{cookie} +} + +// CompositeGlyphs32Checked sends a checked request. +// If an error occurs, it can be retrieved using CompositeGlyphs32Cookie.Check() +func CompositeGlyphs32Checked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs32Cookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CompositeGlyphs32' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(compositeGlyphs32Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie) + return CompositeGlyphs32Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CompositeGlyphs32Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CompositeGlyphs32 +// compositeGlyphs32Request writes a CompositeGlyphs32 request to a byte slice. +func compositeGlyphs32Request(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) []byte { + size := xgb.Pad((28 + xgb.Pad((len(Glyphcmds) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 25 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put32(buf[b:], uint32(Glyphset)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + copy(buf[b:], Glyphcmds[:len(Glyphcmds)]) + b += int(len(Glyphcmds)) + + return buf +} + +// CompositeGlyphs8Cookie is a cookie used only for CompositeGlyphs8 requests. +type CompositeGlyphs8Cookie struct { + *xgb.Cookie +} + +// CompositeGlyphs8 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CompositeGlyphs8(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs8Cookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CompositeGlyphs8' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(compositeGlyphs8Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie) + return CompositeGlyphs8Cookie{cookie} +} + +// CompositeGlyphs8Checked sends a checked request. +// If an error occurs, it can be retrieved using CompositeGlyphs8Cookie.Check() +func CompositeGlyphs8Checked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs8Cookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CompositeGlyphs8' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(compositeGlyphs8Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie) + return CompositeGlyphs8Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CompositeGlyphs8Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CompositeGlyphs8 +// compositeGlyphs8Request writes a CompositeGlyphs8 request to a byte slice. +func compositeGlyphs8Request(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) []byte { + size := xgb.Pad((28 + xgb.Pad((len(Glyphcmds) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 23 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put32(buf[b:], uint32(Glyphset)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + copy(buf[b:], Glyphcmds[:len(Glyphcmds)]) + b += int(len(Glyphcmds)) + + return buf +} + +// CreateAnimCursorCookie is a cookie used only for CreateAnimCursor requests. +type CreateAnimCursorCookie struct { + *xgb.Cookie +} + +// CreateAnimCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateAnimCursor(c *xgb.Conn, Cid xproto.Cursor, Cursors []Animcursorelt) CreateAnimCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateAnimCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createAnimCursorRequest(c, Cid, Cursors), cookie) + return CreateAnimCursorCookie{cookie} +} + +// CreateAnimCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateAnimCursorCookie.Check() +func CreateAnimCursorChecked(c *xgb.Conn, Cid xproto.Cursor, Cursors []Animcursorelt) CreateAnimCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateAnimCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createAnimCursorRequest(c, Cid, Cursors), cookie) + return CreateAnimCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateAnimCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateAnimCursor +// createAnimCursorRequest writes a CreateAnimCursor request to a byte slice. +func createAnimCursorRequest(c *xgb.Conn, Cid xproto.Cursor, Cursors []Animcursorelt) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Cursors) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 31 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cid)) + b += 4 + + b += AnimcursoreltListBytes(buf[b:], Cursors) + + return buf +} + +// CreateConicalGradientCookie is a cookie used only for CreateConicalGradient requests. +type CreateConicalGradientCookie struct { + *xgb.Cookie +} + +// CreateConicalGradient sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateConicalGradient(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateConicalGradientCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateConicalGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createConicalGradientRequest(c, Picture, Center, Angle, NumStops, Stops, Colors), cookie) + return CreateConicalGradientCookie{cookie} +} + +// CreateConicalGradientChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateConicalGradientCookie.Check() +func CreateConicalGradientChecked(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateConicalGradientCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateConicalGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createConicalGradientRequest(c, Picture, Center, Angle, NumStops, Stops, Colors), cookie) + return CreateConicalGradientCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateConicalGradientCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateConicalGradient +// createConicalGradientRequest writes a CreateConicalGradient request to a byte slice. +func createConicalGradientRequest(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) []byte { + size := xgb.Pad(((24 + xgb.Pad((int(NumStops) * 4))) + xgb.Pad((int(NumStops) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 36 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + { + structBytes := Center.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], uint32(Angle)) + b += 4 + + xgb.Put32(buf[b:], NumStops) + b += 4 + + for i := 0; i < int(NumStops); i++ { + xgb.Put32(buf[b:], uint32(Stops[i])) + b += 4 + } + + b += ColorListBytes(buf[b:], Colors) + + return buf +} + +// CreateCursorCookie is a cookie used only for CreateCursor requests. +type CreateCursorCookie struct { + *xgb.Cookie +} + +// CreateCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateCursor(c *xgb.Conn, Cid xproto.Cursor, Source Picture, X uint16, Y uint16) CreateCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createCursorRequest(c, Cid, Source, X, Y), cookie) + return CreateCursorCookie{cookie} +} + +// CreateCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateCursorCookie.Check() +func CreateCursorChecked(c *xgb.Conn, Cid xproto.Cursor, Source Picture, X uint16, Y uint16) CreateCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createCursorRequest(c, Cid, Source, X, Y), cookie) + return CreateCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateCursor +// createCursorRequest writes a CreateCursor request to a byte slice. +func createCursorRequest(c *xgb.Conn, Cid xproto.Cursor, Source Picture, X uint16, Y uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 27 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + xgb.Put16(buf[b:], X) + b += 2 + + xgb.Put16(buf[b:], Y) + b += 2 + + return buf +} + +// CreateGlyphSetCookie is a cookie used only for CreateGlyphSet requests. +type CreateGlyphSetCookie struct { + *xgb.Cookie +} + +// CreateGlyphSet sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateGlyphSet(c *xgb.Conn, Gsid Glyphset, Format Pictformat) CreateGlyphSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createGlyphSetRequest(c, Gsid, Format), cookie) + return CreateGlyphSetCookie{cookie} +} + +// CreateGlyphSetChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateGlyphSetCookie.Check() +func CreateGlyphSetChecked(c *xgb.Conn, Gsid Glyphset, Format Pictformat) CreateGlyphSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createGlyphSetRequest(c, Gsid, Format), cookie) + return CreateGlyphSetCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateGlyphSetCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateGlyphSet +// createGlyphSetRequest writes a CreateGlyphSet request to a byte slice. +func createGlyphSetRequest(c *xgb.Conn, Gsid Glyphset, Format Pictformat) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gsid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Format)) + b += 4 + + return buf +} + +// CreateLinearGradientCookie is a cookie used only for CreateLinearGradient requests. +type CreateLinearGradientCookie struct { + *xgb.Cookie +} + +// CreateLinearGradient sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateLinearGradient(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) CreateLinearGradientCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateLinearGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createLinearGradientRequest(c, Picture, P1, P2, NumStops, Stops, Colors), cookie) + return CreateLinearGradientCookie{cookie} +} + +// CreateLinearGradientChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateLinearGradientCookie.Check() +func CreateLinearGradientChecked(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) CreateLinearGradientCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateLinearGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createLinearGradientRequest(c, Picture, P1, P2, NumStops, Stops, Colors), cookie) + return CreateLinearGradientCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateLinearGradientCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateLinearGradient +// createLinearGradientRequest writes a CreateLinearGradient request to a byte slice. +func createLinearGradientRequest(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) []byte { + size := xgb.Pad(((28 + xgb.Pad((int(NumStops) * 4))) + xgb.Pad((int(NumStops) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 34 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + { + structBytes := P1.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := P2.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], NumStops) + b += 4 + + for i := 0; i < int(NumStops); i++ { + xgb.Put32(buf[b:], uint32(Stops[i])) + b += 4 + } + + b += ColorListBytes(buf[b:], Colors) + + return buf +} + +// CreatePictureCookie is a cookie used only for CreatePicture requests. +type CreatePictureCookie struct { + *xgb.Cookie +} + +// CreatePicture sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreatePicture(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) CreatePictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreatePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createPictureRequest(c, Pid, Drawable, Format, ValueMask, ValueList), cookie) + return CreatePictureCookie{cookie} +} + +// CreatePictureChecked sends a checked request. +// If an error occurs, it can be retrieved using CreatePictureCookie.Check() +func CreatePictureChecked(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) CreatePictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreatePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createPictureRequest(c, Pid, Drawable, Format, ValueMask, ValueList), cookie) + return CreatePictureCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreatePictureCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreatePicture +// createPictureRequest writes a CreatePicture request to a byte slice. +func createPictureRequest(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((20 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Pid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Format)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// CreateRadialGradientCookie is a cookie used only for CreateRadialGradient requests. +type CreateRadialGradientCookie struct { + *xgb.Cookie +} + +// CreateRadialGradient sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRadialGradient(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateRadialGradientCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateRadialGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRadialGradientRequest(c, Picture, Inner, Outer, InnerRadius, OuterRadius, NumStops, Stops, Colors), cookie) + return CreateRadialGradientCookie{cookie} +} + +// CreateRadialGradientChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRadialGradientCookie.Check() +func CreateRadialGradientChecked(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateRadialGradientCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateRadialGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRadialGradientRequest(c, Picture, Inner, Outer, InnerRadius, OuterRadius, NumStops, Stops, Colors), cookie) + return CreateRadialGradientCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRadialGradientCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRadialGradient +// createRadialGradientRequest writes a CreateRadialGradient request to a byte slice. +func createRadialGradientRequest(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) []byte { + size := xgb.Pad(((36 + xgb.Pad((int(NumStops) * 4))) + xgb.Pad((int(NumStops) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 35 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + { + structBytes := Inner.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + { + structBytes := Outer.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], uint32(InnerRadius)) + b += 4 + + xgb.Put32(buf[b:], uint32(OuterRadius)) + b += 4 + + xgb.Put32(buf[b:], NumStops) + b += 4 + + for i := 0; i < int(NumStops); i++ { + xgb.Put32(buf[b:], uint32(Stops[i])) + b += 4 + } + + b += ColorListBytes(buf[b:], Colors) + + return buf +} + +// CreateSolidFillCookie is a cookie used only for CreateSolidFill requests. +type CreateSolidFillCookie struct { + *xgb.Cookie +} + +// CreateSolidFill sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateSolidFill(c *xgb.Conn, Picture Picture, Color Color) CreateSolidFillCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateSolidFill' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createSolidFillRequest(c, Picture, Color), cookie) + return CreateSolidFillCookie{cookie} +} + +// CreateSolidFillChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateSolidFillCookie.Check() +func CreateSolidFillChecked(c *xgb.Conn, Picture Picture, Color Color) CreateSolidFillCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'CreateSolidFill' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createSolidFillRequest(c, Picture, Color), cookie) + return CreateSolidFillCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateSolidFillCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateSolidFill +// createSolidFillRequest writes a CreateSolidFill request to a byte slice. +func createSolidFillRequest(c *xgb.Conn, Picture Picture, Color Color) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 33 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + { + structBytes := Color.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf +} + +// FillRectanglesCookie is a cookie used only for FillRectangles requests. +type FillRectanglesCookie struct { + *xgb.Cookie +} + +// FillRectangles sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FillRectangles(c *xgb.Conn, Op byte, Dst Picture, Color Color, Rects []xproto.Rectangle) FillRectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FillRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(fillRectanglesRequest(c, Op, Dst, Color, Rects), cookie) + return FillRectanglesCookie{cookie} +} + +// FillRectanglesChecked sends a checked request. +// If an error occurs, it can be retrieved using FillRectanglesCookie.Check() +func FillRectanglesChecked(c *xgb.Conn, Op byte, Dst Picture, Color Color, Rects []xproto.Rectangle) FillRectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FillRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(fillRectanglesRequest(c, Op, Dst, Color, Rects), cookie) + return FillRectanglesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FillRectanglesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FillRectangles +// fillRectanglesRequest writes a FillRectangles request to a byte slice. +func fillRectanglesRequest(c *xgb.Conn, Op byte, Dst Picture, Color Color, Rects []xproto.Rectangle) []byte { + size := xgb.Pad((20 + xgb.Pad((len(Rects) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 26 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + { + structBytes := Color.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + b += xproto.RectangleListBytes(buf[b:], Rects) + + return buf +} + +// FreeGlyphSetCookie is a cookie used only for FreeGlyphSet requests. +type FreeGlyphSetCookie struct { + *xgb.Cookie +} + +// FreeGlyphSet sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeGlyphSet(c *xgb.Conn, Glyphset Glyphset) FreeGlyphSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FreeGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freeGlyphSetRequest(c, Glyphset), cookie) + return FreeGlyphSetCookie{cookie} +} + +// FreeGlyphSetChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeGlyphSetCookie.Check() +func FreeGlyphSetChecked(c *xgb.Conn, Glyphset Glyphset) FreeGlyphSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FreeGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freeGlyphSetRequest(c, Glyphset), cookie) + return FreeGlyphSetCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeGlyphSetCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeGlyphSet +// freeGlyphSetRequest writes a FreeGlyphSet request to a byte slice. +func freeGlyphSetRequest(c *xgb.Conn, Glyphset Glyphset) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Glyphset)) + b += 4 + + return buf +} + +// FreeGlyphsCookie is a cookie used only for FreeGlyphs requests. +type FreeGlyphsCookie struct { + *xgb.Cookie +} + +// FreeGlyphs sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeGlyphs(c *xgb.Conn, Glyphset Glyphset, Glyphs []Glyph) FreeGlyphsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FreeGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freeGlyphsRequest(c, Glyphset, Glyphs), cookie) + return FreeGlyphsCookie{cookie} +} + +// FreeGlyphsChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeGlyphsCookie.Check() +func FreeGlyphsChecked(c *xgb.Conn, Glyphset Glyphset, Glyphs []Glyph) FreeGlyphsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FreeGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freeGlyphsRequest(c, Glyphset, Glyphs), cookie) + return FreeGlyphsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeGlyphsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeGlyphs +// freeGlyphsRequest writes a FreeGlyphs request to a byte slice. +func freeGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, Glyphs []Glyph) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Glyphs) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 22 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Glyphset)) + b += 4 + + for i := 0; i < int(len(Glyphs)); i++ { + xgb.Put32(buf[b:], uint32(Glyphs[i])) + b += 4 + } + + return buf +} + +// FreePictureCookie is a cookie used only for FreePicture requests. +type FreePictureCookie struct { + *xgb.Cookie +} + +// FreePicture sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreePicture(c *xgb.Conn, Picture Picture) FreePictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FreePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freePictureRequest(c, Picture), cookie) + return FreePictureCookie{cookie} +} + +// FreePictureChecked sends a checked request. +// If an error occurs, it can be retrieved using FreePictureCookie.Check() +func FreePictureChecked(c *xgb.Conn, Picture Picture) FreePictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'FreePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freePictureRequest(c, Picture), cookie) + return FreePictureCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreePictureCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreePicture +// freePictureRequest writes a FreePicture request to a byte slice. +func freePictureRequest(c *xgb.Conn, Picture Picture) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + return buf +} + +// QueryFiltersCookie is a cookie used only for QueryFilters requests. +type QueryFiltersCookie struct { + *xgb.Cookie +} + +// QueryFilters sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryFiltersCookie.Reply() +func QueryFilters(c *xgb.Conn, Drawable xproto.Drawable) QueryFiltersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryFilters' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryFiltersRequest(c, Drawable), cookie) + return QueryFiltersCookie{cookie} +} + +// QueryFiltersUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryFiltersUnchecked(c *xgb.Conn, Drawable xproto.Drawable) QueryFiltersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryFilters' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryFiltersRequest(c, Drawable), cookie) + return QueryFiltersCookie{cookie} +} + +// QueryFiltersReply represents the data returned from a QueryFilters request. +type QueryFiltersReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAliases uint32 + NumFilters uint32 + // padding: 16 bytes + Aliases []uint16 // size: xgb.Pad((int(NumAliases) * 2)) + Filters []xproto.Str // size: xproto.StrListSize(Filters) +} + +// Reply blocks and returns the reply data for a QueryFilters request. +func (cook QueryFiltersCookie) Reply() (*QueryFiltersReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryFiltersReply(buf), nil +} + +// queryFiltersReply reads a byte slice into a QueryFiltersReply value. +func queryFiltersReply(buf []byte) *QueryFiltersReply { + v := new(QueryFiltersReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAliases = xgb.Get32(buf[b:]) + b += 4 + + v.NumFilters = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + v.Aliases = make([]uint16, v.NumAliases) + for i := 0; i < int(v.NumAliases); i++ { + v.Aliases[i] = xgb.Get16(buf[b:]) + b += 2 + } + + v.Filters = make([]xproto.Str, v.NumFilters) + b += xproto.StrReadList(buf[b:], v.Filters) + + return v +} + +// Write request to wire for QueryFilters +// queryFiltersRequest writes a QueryFilters request to a byte slice. +func queryFiltersRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 29 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// QueryPictFormatsCookie is a cookie used only for QueryPictFormats requests. +type QueryPictFormatsCookie struct { + *xgb.Cookie +} + +// QueryPictFormats sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryPictFormatsCookie.Reply() +func QueryPictFormats(c *xgb.Conn) QueryPictFormatsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryPictFormats' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryPictFormatsRequest(c), cookie) + return QueryPictFormatsCookie{cookie} +} + +// QueryPictFormatsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryPictFormatsUnchecked(c *xgb.Conn) QueryPictFormatsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryPictFormats' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryPictFormatsRequest(c), cookie) + return QueryPictFormatsCookie{cookie} +} + +// QueryPictFormatsReply represents the data returned from a QueryPictFormats request. +type QueryPictFormatsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumFormats uint32 + NumScreens uint32 + NumDepths uint32 + NumVisuals uint32 + NumSubpixel uint32 + // padding: 4 bytes + Formats []Pictforminfo // size: xgb.Pad((int(NumFormats) * 28)) + Screens []Pictscreen // size: PictscreenListSize(Screens) + Subpixels []uint32 // size: xgb.Pad((int(NumSubpixel) * 4)) +} + +// Reply blocks and returns the reply data for a QueryPictFormats request. +func (cook QueryPictFormatsCookie) Reply() (*QueryPictFormatsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryPictFormatsReply(buf), nil +} + +// queryPictFormatsReply reads a byte slice into a QueryPictFormatsReply value. +func queryPictFormatsReply(buf []byte) *QueryPictFormatsReply { + v := new(QueryPictFormatsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumFormats = xgb.Get32(buf[b:]) + b += 4 + + v.NumScreens = xgb.Get32(buf[b:]) + b += 4 + + v.NumDepths = xgb.Get32(buf[b:]) + b += 4 + + v.NumVisuals = xgb.Get32(buf[b:]) + b += 4 + + v.NumSubpixel = xgb.Get32(buf[b:]) + b += 4 + + b += 4 // padding + + v.Formats = make([]Pictforminfo, v.NumFormats) + b += PictforminfoReadList(buf[b:], v.Formats) + + v.Screens = make([]Pictscreen, v.NumScreens) + b += PictscreenReadList(buf[b:], v.Screens) + + v.Subpixels = make([]uint32, v.NumSubpixel) + for i := 0; i < int(v.NumSubpixel); i++ { + v.Subpixels[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for QueryPictFormats +// queryPictFormatsRequest writes a QueryPictFormats request to a byte slice. +func queryPictFormatsRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryPictIndexValuesCookie is a cookie used only for QueryPictIndexValues requests. +type QueryPictIndexValuesCookie struct { + *xgb.Cookie +} + +// QueryPictIndexValues sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryPictIndexValuesCookie.Reply() +func QueryPictIndexValues(c *xgb.Conn, Format Pictformat) QueryPictIndexValuesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryPictIndexValues' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryPictIndexValuesRequest(c, Format), cookie) + return QueryPictIndexValuesCookie{cookie} +} + +// QueryPictIndexValuesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryPictIndexValuesUnchecked(c *xgb.Conn, Format Pictformat) QueryPictIndexValuesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryPictIndexValues' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryPictIndexValuesRequest(c, Format), cookie) + return QueryPictIndexValuesCookie{cookie} +} + +// QueryPictIndexValuesReply represents the data returned from a QueryPictIndexValues request. +type QueryPictIndexValuesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumValues uint32 + // padding: 20 bytes + Values []Indexvalue // size: xgb.Pad((int(NumValues) * 12)) +} + +// Reply blocks and returns the reply data for a QueryPictIndexValues request. +func (cook QueryPictIndexValuesCookie) Reply() (*QueryPictIndexValuesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryPictIndexValuesReply(buf), nil +} + +// queryPictIndexValuesReply reads a byte slice into a QueryPictIndexValuesReply value. +func queryPictIndexValuesReply(buf []byte) *QueryPictIndexValuesReply { + v := new(QueryPictIndexValuesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumValues = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Values = make([]Indexvalue, v.NumValues) + b += IndexvalueReadList(buf[b:], v.Values) + + return v +} + +// Write request to wire for QueryPictIndexValues +// queryPictIndexValuesRequest writes a QueryPictIndexValues request to a byte slice. +func queryPictIndexValuesRequest(c *xgb.Conn, Format Pictformat) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Format)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ClientMajorVersion) + b += 4 + + xgb.Put32(buf[b:], ClientMinorVersion) + b += 4 + + return buf +} + +// ReferenceGlyphSetCookie is a cookie used only for ReferenceGlyphSet requests. +type ReferenceGlyphSetCookie struct { + *xgb.Cookie +} + +// ReferenceGlyphSet sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ReferenceGlyphSet(c *xgb.Conn, Gsid Glyphset, Existing Glyphset) ReferenceGlyphSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'ReferenceGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(referenceGlyphSetRequest(c, Gsid, Existing), cookie) + return ReferenceGlyphSetCookie{cookie} +} + +// ReferenceGlyphSetChecked sends a checked request. +// If an error occurs, it can be retrieved using ReferenceGlyphSetCookie.Check() +func ReferenceGlyphSetChecked(c *xgb.Conn, Gsid Glyphset, Existing Glyphset) ReferenceGlyphSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'ReferenceGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(referenceGlyphSetRequest(c, Gsid, Existing), cookie) + return ReferenceGlyphSetCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ReferenceGlyphSetCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ReferenceGlyphSet +// referenceGlyphSetRequest writes a ReferenceGlyphSet request to a byte slice. +func referenceGlyphSetRequest(c *xgb.Conn, Gsid Glyphset, Existing Glyphset) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gsid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Existing)) + b += 4 + + return buf +} + +// SetPictureClipRectanglesCookie is a cookie used only for SetPictureClipRectangles requests. +type SetPictureClipRectanglesCookie struct { + *xgb.Cookie +} + +// SetPictureClipRectangles sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPictureClipRectangles(c *xgb.Conn, Picture Picture, ClipXOrigin int16, ClipYOrigin int16, Rectangles []xproto.Rectangle) SetPictureClipRectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'SetPictureClipRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPictureClipRectanglesRequest(c, Picture, ClipXOrigin, ClipYOrigin, Rectangles), cookie) + return SetPictureClipRectanglesCookie{cookie} +} + +// SetPictureClipRectanglesChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPictureClipRectanglesCookie.Check() +func SetPictureClipRectanglesChecked(c *xgb.Conn, Picture Picture, ClipXOrigin int16, ClipYOrigin int16, Rectangles []xproto.Rectangle) SetPictureClipRectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'SetPictureClipRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPictureClipRectanglesRequest(c, Picture, ClipXOrigin, ClipYOrigin, Rectangles), cookie) + return SetPictureClipRectanglesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPictureClipRectanglesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPictureClipRectangles +// setPictureClipRectanglesRequest writes a SetPictureClipRectangles request to a byte slice. +func setPictureClipRectanglesRequest(c *xgb.Conn, Picture Picture, ClipXOrigin int16, ClipYOrigin int16, Rectangles []xproto.Rectangle) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + xgb.Put16(buf[b:], uint16(ClipXOrigin)) + b += 2 + + xgb.Put16(buf[b:], uint16(ClipYOrigin)) + b += 2 + + b += xproto.RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// SetPictureFilterCookie is a cookie used only for SetPictureFilter requests. +type SetPictureFilterCookie struct { + *xgb.Cookie +} + +// SetPictureFilter sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPictureFilter(c *xgb.Conn, Picture Picture, FilterLen uint16, Filter string, Values []Fixed) SetPictureFilterCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'SetPictureFilter' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPictureFilterRequest(c, Picture, FilterLen, Filter, Values), cookie) + return SetPictureFilterCookie{cookie} +} + +// SetPictureFilterChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPictureFilterCookie.Check() +func SetPictureFilterChecked(c *xgb.Conn, Picture Picture, FilterLen uint16, Filter string, Values []Fixed) SetPictureFilterCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'SetPictureFilter' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPictureFilterRequest(c, Picture, FilterLen, Filter, Values), cookie) + return SetPictureFilterCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPictureFilterCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPictureFilter +// setPictureFilterRequest writes a SetPictureFilter request to a byte slice. +func setPictureFilterRequest(c *xgb.Conn, Picture Picture, FilterLen uint16, Filter string, Values []Fixed) []byte { + size := xgb.Pad((((12 + xgb.Pad((int(FilterLen) * 1))) + 4) + xgb.Pad((len(Values) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 30 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + xgb.Put16(buf[b:], FilterLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Filter[:FilterLen]) + b += int(FilterLen) + + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(len(Values)); i++ { + xgb.Put32(buf[b:], uint32(Values[i])) + b += 4 + } + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// SetPictureTransformCookie is a cookie used only for SetPictureTransform requests. +type SetPictureTransformCookie struct { + *xgb.Cookie +} + +// SetPictureTransform sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPictureTransform(c *xgb.Conn, Picture Picture, Transform Transform) SetPictureTransformCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'SetPictureTransform' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPictureTransformRequest(c, Picture, Transform), cookie) + return SetPictureTransformCookie{cookie} +} + +// SetPictureTransformChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPictureTransformCookie.Check() +func SetPictureTransformChecked(c *xgb.Conn, Picture Picture, Transform Transform) SetPictureTransformCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'SetPictureTransform' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPictureTransformRequest(c, Picture, Transform), cookie) + return SetPictureTransformCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPictureTransformCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPictureTransform +// setPictureTransformRequest writes a SetPictureTransform request to a byte slice. +func setPictureTransformRequest(c *xgb.Conn, Picture Picture, Transform Transform) []byte { + size := 44 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 28 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + { + structBytes := Transform.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf +} + +// TrapezoidsCookie is a cookie used only for Trapezoids requests. +type TrapezoidsCookie struct { + *xgb.Cookie +} + +// Trapezoids sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Trapezoids(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Traps []Trapezoid) TrapezoidsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'Trapezoids' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(trapezoidsRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Traps), cookie) + return TrapezoidsCookie{cookie} +} + +// TrapezoidsChecked sends a checked request. +// If an error occurs, it can be retrieved using TrapezoidsCookie.Check() +func TrapezoidsChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Traps []Trapezoid) TrapezoidsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'Trapezoids' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(trapezoidsRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Traps), cookie) + return TrapezoidsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook TrapezoidsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Trapezoids +// trapezoidsRequest writes a Trapezoids request to a byte slice. +func trapezoidsRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Traps []Trapezoid) []byte { + size := xgb.Pad((24 + xgb.Pad((len(Traps) * 40)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + b += TrapezoidListBytes(buf[b:], Traps) + + return buf +} + +// TriFanCookie is a cookie used only for TriFan requests. +type TriFanCookie struct { + *xgb.Cookie +} + +// TriFan sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func TriFan(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriFanCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'TriFan' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(triFanRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie) + return TriFanCookie{cookie} +} + +// TriFanChecked sends a checked request. +// If an error occurs, it can be retrieved using TriFanCookie.Check() +func TriFanChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriFanCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'TriFan' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(triFanRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie) + return TriFanCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook TriFanCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for TriFan +// triFanRequest writes a TriFan request to a byte slice. +func triFanRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) []byte { + size := xgb.Pad((24 + xgb.Pad((len(Points) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + b += PointfixListBytes(buf[b:], Points) + + return buf +} + +// TriStripCookie is a cookie used only for TriStrip requests. +type TriStripCookie struct { + *xgb.Cookie +} + +// TriStrip sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func TriStrip(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriStripCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'TriStrip' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(triStripRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie) + return TriStripCookie{cookie} +} + +// TriStripChecked sends a checked request. +// If an error occurs, it can be retrieved using TriStripCookie.Check() +func TriStripChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriStripCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'TriStrip' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(triStripRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie) + return TriStripCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook TriStripCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for TriStrip +// triStripRequest writes a TriStrip request to a byte slice. +func triStripRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) []byte { + size := xgb.Pad((24 + xgb.Pad((len(Points) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + b += PointfixListBytes(buf[b:], Points) + + return buf +} + +// TrianglesCookie is a cookie used only for Triangles requests. +type TrianglesCookie struct { + *xgb.Cookie +} + +// Triangles sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Triangles(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Triangles []Triangle) TrianglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'Triangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(trianglesRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Triangles), cookie) + return TrianglesCookie{cookie} +} + +// TrianglesChecked sends a checked request. +// If an error occurs, it can be retrieved using TrianglesCookie.Check() +func TrianglesChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Triangles []Triangle) TrianglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RENDER"]; !ok { + panic("Cannot issue request 'Triangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(trianglesRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Triangles), cookie) + return TrianglesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook TrianglesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Triangles +// trianglesRequest writes a Triangles request to a byte slice. +func trianglesRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Triangles []Triangle) []byte { + size := xgb.Pad((24 + xgb.Pad((len(Triangles) * 24)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RENDER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Op + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put32(buf[b:], uint32(Dst)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFormat)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + b += TriangleListBytes(buf[b:], Triangles) + + return buf +} diff --git a/vend/xgb/res/res.go b/vend/xgb/res/res.go new file mode 100644 index 0000000..32e331c --- /dev/null +++ b/vend/xgb/res/res.go @@ -0,0 +1,1110 @@ +// Package res is the X client API for the X-Resource extension. +package res + +// This file is automatically generated from res.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the X-Resource extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 10, "X-Resource").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named X-Resource could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["X-Resource"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["X-Resource"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["X-Resource"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["X-Resource"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["X-Resource"] = make(map[int]xgb.NewErrorFun) +} + +type Client struct { + ResourceBase uint32 + ResourceMask uint32 +} + +// ClientRead reads a byte slice into a Client value. +func ClientRead(buf []byte, v *Client) int { + b := 0 + + v.ResourceBase = xgb.Get32(buf[b:]) + b += 4 + + v.ResourceMask = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// ClientReadList reads a byte slice into a list of Client values. +func ClientReadList(buf []byte, dest []Client) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Client{} + b += ClientRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Client value to a byte slice. +func (v Client) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], v.ResourceBase) + b += 4 + + xgb.Put32(buf[b:], v.ResourceMask) + b += 4 + + return buf[:b] +} + +// ClientListBytes writes a list of Client values to a byte slice. +func ClientListBytes(buf []byte, list []Client) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + ClientIdMaskClientXID = 1 + ClientIdMaskLocalClientPID = 2 +) + +type ClientIdSpec struct { + Client uint32 + Mask uint32 +} + +// ClientIdSpecRead reads a byte slice into a ClientIdSpec value. +func ClientIdSpecRead(buf []byte, v *ClientIdSpec) int { + b := 0 + + v.Client = xgb.Get32(buf[b:]) + b += 4 + + v.Mask = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// ClientIdSpecReadList reads a byte slice into a list of ClientIdSpec values. +func ClientIdSpecReadList(buf []byte, dest []ClientIdSpec) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ClientIdSpec{} + b += ClientIdSpecRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ClientIdSpec value to a byte slice. +func (v ClientIdSpec) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], v.Client) + b += 4 + + xgb.Put32(buf[b:], v.Mask) + b += 4 + + return buf[:b] +} + +// ClientIdSpecListBytes writes a list of ClientIdSpec values to a byte slice. +func ClientIdSpecListBytes(buf []byte, list []ClientIdSpec) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type ClientIdValue struct { + Spec ClientIdSpec + Length uint32 + Value []uint32 // size: xgb.Pad(((int(Length) / 4) * 4)) +} + +// ClientIdValueRead reads a byte slice into a ClientIdValue value. +func ClientIdValueRead(buf []byte, v *ClientIdValue) int { + b := 0 + + v.Spec = ClientIdSpec{} + b += ClientIdSpecRead(buf[b:], &v.Spec) + + v.Length = xgb.Get32(buf[b:]) + b += 4 + + v.Value = make([]uint32, (int(v.Length) / 4)) + for i := 0; i < int((int(v.Length) / 4)); i++ { + v.Value[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return b +} + +// ClientIdValueReadList reads a byte slice into a list of ClientIdValue values. +func ClientIdValueReadList(buf []byte, dest []ClientIdValue) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ClientIdValue{} + b += ClientIdValueRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ClientIdValue value to a byte slice. +func (v ClientIdValue) Bytes() []byte { + buf := make([]byte, (12 + xgb.Pad(((int(v.Length) / 4) * 4)))) + b := 0 + + { + structBytes := v.Spec.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], v.Length) + b += 4 + + for i := 0; i < int((int(v.Length) / 4)); i++ { + xgb.Put32(buf[b:], v.Value[i]) + b += 4 + } + + return buf[:b] +} + +// ClientIdValueListBytes writes a list of ClientIdValue values to a byte slice. +func ClientIdValueListBytes(buf []byte, list []ClientIdValue) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ClientIdValueListSize computes the size (bytes) of a list of ClientIdValue values. +func ClientIdValueListSize(list []ClientIdValue) int { + size := 0 + for _, item := range list { + size += (12 + xgb.Pad(((int(item.Length) / 4) * 4))) + } + return size +} + +type ResourceIdSpec struct { + Resource uint32 + Type uint32 +} + +// ResourceIdSpecRead reads a byte slice into a ResourceIdSpec value. +func ResourceIdSpecRead(buf []byte, v *ResourceIdSpec) int { + b := 0 + + v.Resource = xgb.Get32(buf[b:]) + b += 4 + + v.Type = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// ResourceIdSpecReadList reads a byte slice into a list of ResourceIdSpec values. +func ResourceIdSpecReadList(buf []byte, dest []ResourceIdSpec) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ResourceIdSpec{} + b += ResourceIdSpecRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ResourceIdSpec value to a byte slice. +func (v ResourceIdSpec) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], v.Resource) + b += 4 + + xgb.Put32(buf[b:], v.Type) + b += 4 + + return buf[:b] +} + +// ResourceIdSpecListBytes writes a list of ResourceIdSpec values to a byte slice. +func ResourceIdSpecListBytes(buf []byte, list []ResourceIdSpec) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type ResourceSizeSpec struct { + Spec ResourceIdSpec + Bytes_ uint32 + RefCount uint32 + UseCount uint32 +} + +// ResourceSizeSpecRead reads a byte slice into a ResourceSizeSpec value. +func ResourceSizeSpecRead(buf []byte, v *ResourceSizeSpec) int { + b := 0 + + v.Spec = ResourceIdSpec{} + b += ResourceIdSpecRead(buf[b:], &v.Spec) + + v.Bytes_ = xgb.Get32(buf[b:]) + b += 4 + + v.RefCount = xgb.Get32(buf[b:]) + b += 4 + + v.UseCount = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// ResourceSizeSpecReadList reads a byte slice into a list of ResourceSizeSpec values. +func ResourceSizeSpecReadList(buf []byte, dest []ResourceSizeSpec) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ResourceSizeSpec{} + b += ResourceSizeSpecRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ResourceSizeSpec value to a byte slice. +func (v ResourceSizeSpec) Bytes() []byte { + buf := make([]byte, 20) + b := 0 + + { + structBytes := v.Spec.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], v.Bytes_) + b += 4 + + xgb.Put32(buf[b:], v.RefCount) + b += 4 + + xgb.Put32(buf[b:], v.UseCount) + b += 4 + + return buf[:b] +} + +// ResourceSizeSpecListBytes writes a list of ResourceSizeSpec values to a byte slice. +func ResourceSizeSpecListBytes(buf []byte, list []ResourceSizeSpec) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type ResourceSizeValue struct { + Size ResourceSizeSpec + NumCrossReferences uint32 + CrossReferences []ResourceSizeSpec // size: xgb.Pad((int(NumCrossReferences) * 20)) +} + +// ResourceSizeValueRead reads a byte slice into a ResourceSizeValue value. +func ResourceSizeValueRead(buf []byte, v *ResourceSizeValue) int { + b := 0 + + v.Size = ResourceSizeSpec{} + b += ResourceSizeSpecRead(buf[b:], &v.Size) + + v.NumCrossReferences = xgb.Get32(buf[b:]) + b += 4 + + v.CrossReferences = make([]ResourceSizeSpec, v.NumCrossReferences) + b += ResourceSizeSpecReadList(buf[b:], v.CrossReferences) + + return b +} + +// ResourceSizeValueReadList reads a byte slice into a list of ResourceSizeValue values. +func ResourceSizeValueReadList(buf []byte, dest []ResourceSizeValue) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ResourceSizeValue{} + b += ResourceSizeValueRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ResourceSizeValue value to a byte slice. +func (v ResourceSizeValue) Bytes() []byte { + buf := make([]byte, (24 + xgb.Pad((int(v.NumCrossReferences) * 20)))) + b := 0 + + { + structBytes := v.Size.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], v.NumCrossReferences) + b += 4 + + b += ResourceSizeSpecListBytes(buf[b:], v.CrossReferences) + + return buf[:b] +} + +// ResourceSizeValueListBytes writes a list of ResourceSizeValue values to a byte slice. +func ResourceSizeValueListBytes(buf []byte, list []ResourceSizeValue) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ResourceSizeValueListSize computes the size (bytes) of a list of ResourceSizeValue values. +func ResourceSizeValueListSize(list []ResourceSizeValue) int { + size := 0 + for _, item := range list { + size += (24 + xgb.Pad((int(item.NumCrossReferences) * 20))) + } + return size +} + +type Type struct { + ResourceType xproto.Atom + Count uint32 +} + +// TypeRead reads a byte slice into a Type value. +func TypeRead(buf []byte, v *Type) int { + b := 0 + + v.ResourceType = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Count = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// TypeReadList reads a byte slice into a list of Type values. +func TypeReadList(buf []byte, dest []Type) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Type{} + b += TypeRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Type value to a byte slice. +func (v Type) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.ResourceType)) + b += 4 + + xgb.Put32(buf[b:], v.Count) + b += 4 + + return buf[:b] +} + +// TypeListBytes writes a list of Type values to a byte slice. +func TypeListBytes(buf []byte, list []Type) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// QueryClientIdsCookie is a cookie used only for QueryClientIds requests. +type QueryClientIdsCookie struct { + *xgb.Cookie +} + +// QueryClientIds sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryClientIdsCookie.Reply() +func QueryClientIds(c *xgb.Conn, NumSpecs uint32, Specs []ClientIdSpec) QueryClientIdsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClientIds' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryClientIdsRequest(c, NumSpecs, Specs), cookie) + return QueryClientIdsCookie{cookie} +} + +// QueryClientIdsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryClientIdsUnchecked(c *xgb.Conn, NumSpecs uint32, Specs []ClientIdSpec) QueryClientIdsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClientIds' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryClientIdsRequest(c, NumSpecs, Specs), cookie) + return QueryClientIdsCookie{cookie} +} + +// QueryClientIdsReply represents the data returned from a QueryClientIds request. +type QueryClientIdsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumIds uint32 + // padding: 20 bytes + Ids []ClientIdValue // size: ClientIdValueListSize(Ids) +} + +// Reply blocks and returns the reply data for a QueryClientIds request. +func (cook QueryClientIdsCookie) Reply() (*QueryClientIdsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryClientIdsReply(buf), nil +} + +// queryClientIdsReply reads a byte slice into a QueryClientIdsReply value. +func queryClientIdsReply(buf []byte) *QueryClientIdsReply { + v := new(QueryClientIdsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumIds = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Ids = make([]ClientIdValue, v.NumIds) + b += ClientIdValueReadList(buf[b:], v.Ids) + + return v +} + +// Write request to wire for QueryClientIds +// queryClientIdsRequest writes a QueryClientIds request to a byte slice. +func queryClientIdsRequest(c *xgb.Conn, NumSpecs uint32, Specs []ClientIdSpec) []byte { + size := xgb.Pad((8 + xgb.Pad((int(NumSpecs) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["X-Resource"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], NumSpecs) + b += 4 + + b += ClientIdSpecListBytes(buf[b:], Specs) + + return buf +} + +// QueryClientPixmapBytesCookie is a cookie used only for QueryClientPixmapBytes requests. +type QueryClientPixmapBytesCookie struct { + *xgb.Cookie +} + +// QueryClientPixmapBytes sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryClientPixmapBytesCookie.Reply() +func QueryClientPixmapBytes(c *xgb.Conn, Xid uint32) QueryClientPixmapBytesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClientPixmapBytes' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryClientPixmapBytesRequest(c, Xid), cookie) + return QueryClientPixmapBytesCookie{cookie} +} + +// QueryClientPixmapBytesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryClientPixmapBytesUnchecked(c *xgb.Conn, Xid uint32) QueryClientPixmapBytesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClientPixmapBytes' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryClientPixmapBytesRequest(c, Xid), cookie) + return QueryClientPixmapBytesCookie{cookie} +} + +// QueryClientPixmapBytesReply represents the data returned from a QueryClientPixmapBytes request. +type QueryClientPixmapBytesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Bytes_ uint32 + BytesOverflow uint32 +} + +// Reply blocks and returns the reply data for a QueryClientPixmapBytes request. +func (cook QueryClientPixmapBytesCookie) Reply() (*QueryClientPixmapBytesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryClientPixmapBytesReply(buf), nil +} + +// queryClientPixmapBytesReply reads a byte slice into a QueryClientPixmapBytesReply value. +func queryClientPixmapBytesReply(buf []byte) *QueryClientPixmapBytesReply { + v := new(QueryClientPixmapBytesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Bytes_ = xgb.Get32(buf[b:]) + b += 4 + + v.BytesOverflow = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for QueryClientPixmapBytes +// queryClientPixmapBytesRequest writes a QueryClientPixmapBytes request to a byte slice. +func queryClientPixmapBytesRequest(c *xgb.Conn, Xid uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["X-Resource"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Xid) + b += 4 + + return buf +} + +// QueryClientResourcesCookie is a cookie used only for QueryClientResources requests. +type QueryClientResourcesCookie struct { + *xgb.Cookie +} + +// QueryClientResources sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryClientResourcesCookie.Reply() +func QueryClientResources(c *xgb.Conn, Xid uint32) QueryClientResourcesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClientResources' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryClientResourcesRequest(c, Xid), cookie) + return QueryClientResourcesCookie{cookie} +} + +// QueryClientResourcesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryClientResourcesUnchecked(c *xgb.Conn, Xid uint32) QueryClientResourcesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClientResources' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryClientResourcesRequest(c, Xid), cookie) + return QueryClientResourcesCookie{cookie} +} + +// QueryClientResourcesReply represents the data returned from a QueryClientResources request. +type QueryClientResourcesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumTypes uint32 + // padding: 20 bytes + Types []Type // size: xgb.Pad((int(NumTypes) * 8)) +} + +// Reply blocks and returns the reply data for a QueryClientResources request. +func (cook QueryClientResourcesCookie) Reply() (*QueryClientResourcesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryClientResourcesReply(buf), nil +} + +// queryClientResourcesReply reads a byte slice into a QueryClientResourcesReply value. +func queryClientResourcesReply(buf []byte) *QueryClientResourcesReply { + v := new(QueryClientResourcesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumTypes = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Types = make([]Type, v.NumTypes) + b += TypeReadList(buf[b:], v.Types) + + return v +} + +// Write request to wire for QueryClientResources +// queryClientResourcesRequest writes a QueryClientResources request to a byte slice. +func queryClientResourcesRequest(c *xgb.Conn, Xid uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["X-Resource"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Xid) + b += 4 + + return buf +} + +// QueryClientsCookie is a cookie used only for QueryClients requests. +type QueryClientsCookie struct { + *xgb.Cookie +} + +// QueryClients sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryClientsCookie.Reply() +func QueryClients(c *xgb.Conn) QueryClientsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClients' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryClientsRequest(c), cookie) + return QueryClientsCookie{cookie} +} + +// QueryClientsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryClientsUnchecked(c *xgb.Conn) QueryClientsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryClients' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryClientsRequest(c), cookie) + return QueryClientsCookie{cookie} +} + +// QueryClientsReply represents the data returned from a QueryClients request. +type QueryClientsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumClients uint32 + // padding: 20 bytes + Clients []Client // size: xgb.Pad((int(NumClients) * 8)) +} + +// Reply blocks and returns the reply data for a QueryClients request. +func (cook QueryClientsCookie) Reply() (*QueryClientsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryClientsReply(buf), nil +} + +// queryClientsReply reads a byte slice into a QueryClientsReply value. +func queryClientsReply(buf []byte) *QueryClientsReply { + v := new(QueryClientsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumClients = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Clients = make([]Client, v.NumClients) + b += ClientReadList(buf[b:], v.Clients) + + return v +} + +// Write request to wire for QueryClients +// queryClientsRequest writes a QueryClients request to a byte slice. +func queryClientsRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["X-Resource"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryResourceBytesCookie is a cookie used only for QueryResourceBytes requests. +type QueryResourceBytesCookie struct { + *xgb.Cookie +} + +// QueryResourceBytes sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryResourceBytesCookie.Reply() +func QueryResourceBytes(c *xgb.Conn, Client uint32, NumSpecs uint32, Specs []ResourceIdSpec) QueryResourceBytesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryResourceBytes' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryResourceBytesRequest(c, Client, NumSpecs, Specs), cookie) + return QueryResourceBytesCookie{cookie} +} + +// QueryResourceBytesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryResourceBytesUnchecked(c *xgb.Conn, Client uint32, NumSpecs uint32, Specs []ResourceIdSpec) QueryResourceBytesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryResourceBytes' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryResourceBytesRequest(c, Client, NumSpecs, Specs), cookie) + return QueryResourceBytesCookie{cookie} +} + +// QueryResourceBytesReply represents the data returned from a QueryResourceBytes request. +type QueryResourceBytesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumSizes uint32 + // padding: 20 bytes + Sizes []ResourceSizeValue // size: ResourceSizeValueListSize(Sizes) +} + +// Reply blocks and returns the reply data for a QueryResourceBytes request. +func (cook QueryResourceBytesCookie) Reply() (*QueryResourceBytesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryResourceBytesReply(buf), nil +} + +// queryResourceBytesReply reads a byte slice into a QueryResourceBytesReply value. +func queryResourceBytesReply(buf []byte) *QueryResourceBytesReply { + v := new(QueryResourceBytesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumSizes = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Sizes = make([]ResourceSizeValue, v.NumSizes) + b += ResourceSizeValueReadList(buf[b:], v.Sizes) + + return v +} + +// Write request to wire for QueryResourceBytes +// queryResourceBytesRequest writes a QueryResourceBytes request to a byte slice. +func queryResourceBytesRequest(c *xgb.Conn, Client uint32, NumSpecs uint32, Specs []ResourceIdSpec) []byte { + size := xgb.Pad((12 + xgb.Pad((int(NumSpecs) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["X-Resource"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Client) + b += 4 + + xgb.Put32(buf[b:], NumSpecs) + b += 4 + + b += ResourceIdSpecListBytes(buf[b:], Specs) + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajor byte, ClientMinor byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajor, ClientMinor), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajor byte, ClientMinor byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["X-Resource"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'X-Resource'. res.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajor, ClientMinor), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ServerMajor uint16 + ServerMinor uint16 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ServerMajor = xgb.Get16(buf[b:]) + b += 2 + + v.ServerMinor = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajor byte, ClientMinor byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["X-Resource"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = ClientMajor + b += 1 + + buf[b] = ClientMinor + b += 1 + + return buf +} diff --git a/vend/xgb/screensaver/screensaver.go b/vend/xgb/screensaver/screensaver.go new file mode 100644 index 0000000..1112c49 --- /dev/null +++ b/vend/xgb/screensaver/screensaver.go @@ -0,0 +1,690 @@ +// Package screensaver is the X client API for the MIT-SCREEN-SAVER extension. +package screensaver + +// This file is automatically generated from screensaver.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the MIT-SCREEN-SAVER extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 16, "MIT-SCREEN-SAVER").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named MIT-SCREEN-SAVER could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["MIT-SCREEN-SAVER"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["MIT-SCREEN-SAVER"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["MIT-SCREEN-SAVER"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["MIT-SCREEN-SAVER"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["MIT-SCREEN-SAVER"] = make(map[int]xgb.NewErrorFun) +} + +const ( + EventNotifyMask = 1 + EventCycleMask = 2 +) + +const ( + KindBlanked = 0 + KindInternal = 1 + KindExternal = 2 +) + +// Notify is the event number for a NotifyEvent. +const Notify = 0 + +type NotifyEvent struct { + Sequence uint16 + State byte + Time xproto.Timestamp + Root xproto.Window + Window xproto.Window + Kind byte + Forced bool + // padding: 14 bytes +} + +// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice. +func NotifyEventNew(buf []byte) xgb.Event { + v := NotifyEvent{} + b := 1 // don't read event number + + v.State = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Kind = buf[b] + b += 1 + + if buf[b] == 1 { + v.Forced = true + } else { + v.Forced = false + } + b += 1 + + b += 14 // padding + + return v +} + +// Bytes writes a NotifyEvent value to a byte slice. +func (v NotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = v.State + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + buf[b] = v.Kind + b += 1 + + if v.Forced { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 14 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the Notify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v NotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of NotifyEvent. +func (v NotifyEvent) String() string { + fieldVals := make([]string, 0, 7) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Kind: %d", v.Kind)) + fieldVals = append(fieldVals, xgb.Sprintf("Forced: %t", v.Forced)) + return "Notify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["MIT-SCREEN-SAVER"][0] = NotifyEventNew +} + +const ( + StateOff = 0 + StateOn = 1 + StateCycle = 2 + StateDisabled = 3 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// QueryInfoCookie is a cookie used only for QueryInfo requests. +type QueryInfoCookie struct { + *xgb.Cookie +} + +// QueryInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryInfoCookie.Reply() +func QueryInfo(c *xgb.Conn, Drawable xproto.Drawable) QueryInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'QueryInfo' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryInfoRequest(c, Drawable), cookie) + return QueryInfoCookie{cookie} +} + +// QueryInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryInfoUnchecked(c *xgb.Conn, Drawable xproto.Drawable) QueryInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'QueryInfo' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryInfoRequest(c, Drawable), cookie) + return QueryInfoCookie{cookie} +} + +// QueryInfoReply represents the data returned from a QueryInfo request. +type QueryInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + State byte + SaverWindow xproto.Window + MsUntilServer uint32 + MsSinceUserInput uint32 + EventMask uint32 + Kind byte + // padding: 7 bytes +} + +// Reply blocks and returns the reply data for a QueryInfo request. +func (cook QueryInfoCookie) Reply() (*QueryInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryInfoReply(buf), nil +} + +// queryInfoReply reads a byte slice into a QueryInfoReply value. +func queryInfoReply(buf []byte) *QueryInfoReply { + v := new(QueryInfoReply) + b := 1 // skip reply determinant + + v.State = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.SaverWindow = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.MsUntilServer = xgb.Get32(buf[b:]) + b += 4 + + v.MsSinceUserInput = xgb.Get32(buf[b:]) + b += 4 + + v.EventMask = xgb.Get32(buf[b:]) + b += 4 + + v.Kind = buf[b] + b += 1 + + b += 7 // padding + + return v +} + +// Write request to wire for QueryInfo +// queryInfoRequest writes a QueryInfo request to a byte slice. +func queryInfoRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SCREEN-SAVER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion byte, ClientMinorVersion byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion byte, ClientMinorVersion byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ServerMajorVersion uint16 + ServerMinorVersion uint16 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ServerMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ServerMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + b += 20 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion byte, ClientMinorVersion byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SCREEN-SAVER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = ClientMajorVersion + b += 1 + + buf[b] = ClientMinorVersion + b += 1 + + b += 2 // padding + + return buf +} + +// SelectInputCookie is a cookie used only for SelectInput requests. +type SelectInputCookie struct { + *xgb.Cookie +} + +// SelectInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectInput(c *xgb.Conn, Drawable xproto.Drawable, EventMask uint32) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectInputRequest(c, Drawable, EventMask), cookie) + return SelectInputCookie{cookie} +} + +// SelectInputChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectInputCookie.Check() +func SelectInputChecked(c *xgb.Conn, Drawable xproto.Drawable, EventMask uint32) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectInputRequest(c, Drawable, EventMask), cookie) + return SelectInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectInput +// selectInputRequest writes a SelectInput request to a byte slice. +func selectInputRequest(c *xgb.Conn, Drawable xproto.Drawable, EventMask uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SCREEN-SAVER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], EventMask) + b += 4 + + return buf +} + +// SetAttributesCookie is a cookie used only for SetAttributes requests. +type SetAttributesCookie struct { + *xgb.Cookie +} + +// SetAttributes sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +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 { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'SetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setAttributesRequest(c, Drawable, X, Y, Width, Height, BorderWidth, Class, Depth, Visual, ValueMask, ValueList), cookie) + return SetAttributesCookie{cookie} +} + +// SetAttributesChecked sends a checked request. +// If an error occurs, it can be retrieved using SetAttributesCookie.Check() +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 { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'SetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setAttributesRequest(c, Drawable, X, Y, Width, Height, BorderWidth, Class, Depth, Visual, ValueMask, ValueList), cookie) + return SetAttributesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetAttributesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetAttributes +// setAttributesRequest writes a SetAttributes request to a byte slice. +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 { + size := xgb.Pad((28 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SCREEN-SAVER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put16(buf[b:], BorderWidth) + b += 2 + + buf[b] = Class + b += 1 + + buf[b] = Depth + b += 1 + + xgb.Put32(buf[b:], uint32(Visual)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// SuspendCookie is a cookie used only for Suspend requests. +type SuspendCookie struct { + *xgb.Cookie +} + +// Suspend sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Suspend(c *xgb.Conn, Suspend uint32) SuspendCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'Suspend' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(suspendRequest(c, Suspend), cookie) + return SuspendCookie{cookie} +} + +// SuspendChecked sends a checked request. +// If an error occurs, it can be retrieved using SuspendCookie.Check() +func SuspendChecked(c *xgb.Conn, Suspend uint32) SuspendCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'Suspend' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(suspendRequest(c, Suspend), cookie) + return SuspendCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SuspendCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Suspend +// suspendRequest writes a Suspend request to a byte slice. +func suspendRequest(c *xgb.Conn, Suspend uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SCREEN-SAVER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Suspend) + b += 4 + + return buf +} + +// UnsetAttributesCookie is a cookie used only for UnsetAttributes requests. +type UnsetAttributesCookie struct { + *xgb.Cookie +} + +// UnsetAttributes sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnsetAttributes(c *xgb.Conn, Drawable xproto.Drawable) UnsetAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'UnsetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(unsetAttributesRequest(c, Drawable), cookie) + return UnsetAttributesCookie{cookie} +} + +// UnsetAttributesChecked sends a checked request. +// If an error occurs, it can be retrieved using UnsetAttributesCookie.Check() +func UnsetAttributesChecked(c *xgb.Conn, Drawable xproto.Drawable) UnsetAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { + panic("Cannot issue request 'UnsetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(unsetAttributesRequest(c, Drawable), cookie) + return UnsetAttributesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnsetAttributesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnsetAttributes +// unsetAttributesRequest writes a UnsetAttributes request to a byte slice. +func unsetAttributesRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SCREEN-SAVER"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} diff --git a/vend/xgb/shape/shape.go b/vend/xgb/shape/shape.go new file mode 100644 index 0000000..42b3f9f --- /dev/null +++ b/vend/xgb/shape/shape.go @@ -0,0 +1,1025 @@ +// Package shape is the X client API for the SHAPE extension. +package shape + +// This file is automatically generated from shape.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the SHAPE extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 5, "SHAPE").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named SHAPE could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["SHAPE"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["SHAPE"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["SHAPE"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["SHAPE"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["SHAPE"] = make(map[int]xgb.NewErrorFun) +} + +type Kind byte + +// Notify is the event number for a NotifyEvent. +const Notify = 0 + +type NotifyEvent struct { + Sequence uint16 + ShapeKind Kind + AffectedWindow xproto.Window + ExtentsX int16 + ExtentsY int16 + ExtentsWidth uint16 + ExtentsHeight uint16 + ServerTime xproto.Timestamp + Shaped bool + // padding: 11 bytes +} + +// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice. +func NotifyEventNew(buf []byte) xgb.Event { + v := NotifyEvent{} + b := 1 // don't read event number + + v.ShapeKind = Kind(buf[b]) + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.AffectedWindow = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.ExtentsX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.ExtentsY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.ExtentsWidth = xgb.Get16(buf[b:]) + b += 2 + + v.ExtentsHeight = xgb.Get16(buf[b:]) + b += 2 + + v.ServerTime = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.Shaped = true + } else { + v.Shaped = false + } + b += 1 + + b += 11 // padding + + return v +} + +// Bytes writes a NotifyEvent value to a byte slice. +func (v NotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = byte(v.ShapeKind) + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.AffectedWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.ExtentsX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.ExtentsY)) + b += 2 + + xgb.Put16(buf[b:], v.ExtentsWidth) + b += 2 + + xgb.Put16(buf[b:], v.ExtentsHeight) + b += 2 + + xgb.Put32(buf[b:], uint32(v.ServerTime)) + b += 4 + + if v.Shaped { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 11 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the Notify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v NotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of NotifyEvent. +func (v NotifyEvent) String() string { + fieldVals := make([]string, 0, 9) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("ShapeKind: %d", v.ShapeKind)) + fieldVals = append(fieldVals, xgb.Sprintf("AffectedWindow: %d", v.AffectedWindow)) + fieldVals = append(fieldVals, xgb.Sprintf("ExtentsX: %d", v.ExtentsX)) + fieldVals = append(fieldVals, xgb.Sprintf("ExtentsY: %d", v.ExtentsY)) + fieldVals = append(fieldVals, xgb.Sprintf("ExtentsWidth: %d", v.ExtentsWidth)) + fieldVals = append(fieldVals, xgb.Sprintf("ExtentsHeight: %d", v.ExtentsHeight)) + fieldVals = append(fieldVals, xgb.Sprintf("ServerTime: %d", v.ServerTime)) + fieldVals = append(fieldVals, xgb.Sprintf("Shaped: %t", v.Shaped)) + return "Notify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["SHAPE"][0] = NotifyEventNew +} + +type Op byte + +const ( + SkBounding = 0 + SkClip = 1 + SkInput = 2 +) + +const ( + SoSet = 0 + SoUnion = 1 + SoIntersect = 2 + SoSubtract = 3 + SoInvert = 4 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CombineCookie is a cookie used only for Combine requests. +type CombineCookie struct { + *xgb.Cookie +} + +// Combine sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Combine(c *xgb.Conn, Operation Op, DestinationKind Kind, SourceKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16, SourceWindow xproto.Window) CombineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Combine' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(combineRequest(c, Operation, DestinationKind, SourceKind, DestinationWindow, XOffset, YOffset, SourceWindow), cookie) + return CombineCookie{cookie} +} + +// CombineChecked sends a checked request. +// If an error occurs, it can be retrieved using CombineCookie.Check() +func CombineChecked(c *xgb.Conn, Operation Op, DestinationKind Kind, SourceKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16, SourceWindow xproto.Window) CombineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Combine' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(combineRequest(c, Operation, DestinationKind, SourceKind, DestinationWindow, XOffset, YOffset, SourceWindow), cookie) + return CombineCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CombineCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Combine +// combineRequest writes a Combine request to a byte slice. +func combineRequest(c *xgb.Conn, Operation Op, DestinationKind Kind, SourceKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16, SourceWindow xproto.Window) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = byte(Operation) + b += 1 + + buf[b] = byte(DestinationKind) + b += 1 + + buf[b] = byte(SourceKind) + b += 1 + + b += 1 // padding + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOffset)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOffset)) + b += 2 + + xgb.Put32(buf[b:], uint32(SourceWindow)) + b += 4 + + return buf +} + +// GetRectanglesCookie is a cookie used only for GetRectangles requests. +type GetRectanglesCookie struct { + *xgb.Cookie +} + +// GetRectangles sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetRectanglesCookie.Reply() +func GetRectangles(c *xgb.Conn, Window xproto.Window, SourceKind Kind) GetRectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'GetRectangles' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getRectanglesRequest(c, Window, SourceKind), cookie) + return GetRectanglesCookie{cookie} +} + +// GetRectanglesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetRectanglesUnchecked(c *xgb.Conn, Window xproto.Window, SourceKind Kind) GetRectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'GetRectangles' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getRectanglesRequest(c, Window, SourceKind), cookie) + return GetRectanglesCookie{cookie} +} + +// GetRectanglesReply represents the data returned from a GetRectangles request. +type GetRectanglesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Ordering byte + RectanglesLen uint32 + // padding: 20 bytes + Rectangles []xproto.Rectangle // size: xgb.Pad((int(RectanglesLen) * 8)) +} + +// Reply blocks and returns the reply data for a GetRectangles request. +func (cook GetRectanglesCookie) Reply() (*GetRectanglesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getRectanglesReply(buf), nil +} + +// getRectanglesReply reads a byte slice into a GetRectanglesReply value. +func getRectanglesReply(buf []byte) *GetRectanglesReply { + v := new(GetRectanglesReply) + b := 1 // skip reply determinant + + v.Ordering = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RectanglesLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Rectangles = make([]xproto.Rectangle, v.RectanglesLen) + b += xproto.RectangleReadList(buf[b:], v.Rectangles) + + return v +} + +// Write request to wire for GetRectangles +// getRectanglesRequest writes a GetRectangles request to a byte slice. +func getRectanglesRequest(c *xgb.Conn, Window xproto.Window, SourceKind Kind) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + buf[b] = byte(SourceKind) + b += 1 + + b += 3 // padding + + return buf +} + +// InputSelectedCookie is a cookie used only for InputSelected requests. +type InputSelectedCookie struct { + *xgb.Cookie +} + +// InputSelected sends a checked request. +// If an error occurs, it will be returned with the reply by calling InputSelectedCookie.Reply() +func InputSelected(c *xgb.Conn, DestinationWindow xproto.Window) InputSelectedCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'InputSelected' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(inputSelectedRequest(c, DestinationWindow), cookie) + return InputSelectedCookie{cookie} +} + +// InputSelectedUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func InputSelectedUnchecked(c *xgb.Conn, DestinationWindow xproto.Window) InputSelectedCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'InputSelected' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(inputSelectedRequest(c, DestinationWindow), cookie) + return InputSelectedCookie{cookie} +} + +// InputSelectedReply represents the data returned from a InputSelected request. +type InputSelectedReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Enabled bool +} + +// Reply blocks and returns the reply data for a InputSelected request. +func (cook InputSelectedCookie) Reply() (*InputSelectedReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return inputSelectedReply(buf), nil +} + +// inputSelectedReply reads a byte slice into a InputSelectedReply value. +func inputSelectedReply(buf []byte) *InputSelectedReply { + v := new(InputSelectedReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.Enabled = true + } else { + v.Enabled = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for InputSelected +// inputSelectedRequest writes a InputSelected request to a byte slice. +func inputSelectedRequest(c *xgb.Conn, DestinationWindow xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + return buf +} + +// MaskCookie is a cookie used only for Mask requests. +type MaskCookie struct { + *xgb.Cookie +} + +// Mask sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Mask(c *xgb.Conn, Operation Op, DestinationKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16, SourceBitmap xproto.Pixmap) MaskCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Mask' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(maskRequest(c, Operation, DestinationKind, DestinationWindow, XOffset, YOffset, SourceBitmap), cookie) + return MaskCookie{cookie} +} + +// MaskChecked sends a checked request. +// If an error occurs, it can be retrieved using MaskCookie.Check() +func MaskChecked(c *xgb.Conn, Operation Op, DestinationKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16, SourceBitmap xproto.Pixmap) MaskCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Mask' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(maskRequest(c, Operation, DestinationKind, DestinationWindow, XOffset, YOffset, SourceBitmap), cookie) + return MaskCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook MaskCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Mask +// maskRequest writes a Mask request to a byte slice. +func maskRequest(c *xgb.Conn, Operation Op, DestinationKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16, SourceBitmap xproto.Pixmap) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = byte(Operation) + b += 1 + + buf[b] = byte(DestinationKind) + b += 1 + + b += 2 // padding + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOffset)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOffset)) + b += 2 + + xgb.Put32(buf[b:], uint32(SourceBitmap)) + b += 4 + + return buf +} + +// OffsetCookie is a cookie used only for Offset requests. +type OffsetCookie struct { + *xgb.Cookie +} + +// Offset sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Offset(c *xgb.Conn, DestinationKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16) OffsetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Offset' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(offsetRequest(c, DestinationKind, DestinationWindow, XOffset, YOffset), cookie) + return OffsetCookie{cookie} +} + +// OffsetChecked sends a checked request. +// If an error occurs, it can be retrieved using OffsetCookie.Check() +func OffsetChecked(c *xgb.Conn, DestinationKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16) OffsetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Offset' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(offsetRequest(c, DestinationKind, DestinationWindow, XOffset, YOffset), cookie) + return OffsetCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook OffsetCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Offset +// offsetRequest writes a Offset request to a byte slice. +func offsetRequest(c *xgb.Conn, DestinationKind Kind, DestinationWindow xproto.Window, XOffset int16, YOffset int16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = byte(DestinationKind) + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOffset)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOffset)) + b += 2 + + return buf +} + +// QueryExtentsCookie is a cookie used only for QueryExtents requests. +type QueryExtentsCookie struct { + *xgb.Cookie +} + +// QueryExtents sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryExtentsCookie.Reply() +func QueryExtents(c *xgb.Conn, DestinationWindow xproto.Window) QueryExtentsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'QueryExtents' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryExtentsRequest(c, DestinationWindow), cookie) + return QueryExtentsCookie{cookie} +} + +// QueryExtentsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryExtentsUnchecked(c *xgb.Conn, DestinationWindow xproto.Window) QueryExtentsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'QueryExtents' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryExtentsRequest(c, DestinationWindow), cookie) + return QueryExtentsCookie{cookie} +} + +// QueryExtentsReply represents the data returned from a QueryExtents request. +type QueryExtentsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + BoundingShaped bool + ClipShaped bool + // padding: 2 bytes + BoundingShapeExtentsX int16 + BoundingShapeExtentsY int16 + BoundingShapeExtentsWidth uint16 + BoundingShapeExtentsHeight uint16 + ClipShapeExtentsX int16 + ClipShapeExtentsY int16 + ClipShapeExtentsWidth uint16 + ClipShapeExtentsHeight uint16 +} + +// Reply blocks and returns the reply data for a QueryExtents request. +func (cook QueryExtentsCookie) Reply() (*QueryExtentsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryExtentsReply(buf), nil +} + +// queryExtentsReply reads a byte slice into a QueryExtentsReply value. +func queryExtentsReply(buf []byte) *QueryExtentsReply { + v := new(QueryExtentsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.BoundingShaped = true + } else { + v.BoundingShaped = false + } + b += 1 + + if buf[b] == 1 { + v.ClipShaped = true + } else { + v.ClipShaped = false + } + b += 1 + + b += 2 // padding + + v.BoundingShapeExtentsX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.BoundingShapeExtentsY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.BoundingShapeExtentsWidth = xgb.Get16(buf[b:]) + b += 2 + + v.BoundingShapeExtentsHeight = xgb.Get16(buf[b:]) + b += 2 + + v.ClipShapeExtentsX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.ClipShapeExtentsY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.ClipShapeExtentsWidth = xgb.Get16(buf[b:]) + b += 2 + + v.ClipShapeExtentsHeight = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryExtents +// queryExtentsRequest writes a QueryExtents request to a byte slice. +func queryExtentsRequest(c *xgb.Conn, DestinationWindow xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint16 + MinorVersion uint16 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// RectanglesCookie is a cookie used only for Rectangles requests. +type RectanglesCookie struct { + *xgb.Cookie +} + +// Rectangles sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Rectangles(c *xgb.Conn, Operation Op, DestinationKind Kind, Ordering byte, DestinationWindow xproto.Window, XOffset int16, YOffset int16, Rectangles []xproto.Rectangle) RectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Rectangles' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(rectanglesRequest(c, Operation, DestinationKind, Ordering, DestinationWindow, XOffset, YOffset, Rectangles), cookie) + return RectanglesCookie{cookie} +} + +// RectanglesChecked sends a checked request. +// If an error occurs, it can be retrieved using RectanglesCookie.Check() +func RectanglesChecked(c *xgb.Conn, Operation Op, DestinationKind Kind, Ordering byte, DestinationWindow xproto.Window, XOffset int16, YOffset int16, Rectangles []xproto.Rectangle) RectanglesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'Rectangles' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(rectanglesRequest(c, Operation, DestinationKind, Ordering, DestinationWindow, XOffset, YOffset, Rectangles), cookie) + return RectanglesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RectanglesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Rectangles +// rectanglesRequest writes a Rectangles request to a byte slice. +func rectanglesRequest(c *xgb.Conn, Operation Op, DestinationKind Kind, Ordering byte, DestinationWindow xproto.Window, XOffset int16, YOffset int16, Rectangles []xproto.Rectangle) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = byte(Operation) + b += 1 + + buf[b] = byte(DestinationKind) + b += 1 + + buf[b] = Ordering + b += 1 + + b += 1 // padding + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOffset)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOffset)) + b += 2 + + b += xproto.RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// SelectInputCookie is a cookie used only for SelectInput requests. +type SelectInputCookie struct { + *xgb.Cookie +} + +// SelectInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectInput(c *xgb.Conn, DestinationWindow xproto.Window, Enable bool) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectInputRequest(c, DestinationWindow, Enable), cookie) + return SelectInputCookie{cookie} +} + +// SelectInputChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectInputCookie.Check() +func SelectInputChecked(c *xgb.Conn, DestinationWindow xproto.Window, Enable bool) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SHAPE"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'SHAPE'. shape.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectInputRequest(c, DestinationWindow, Enable), cookie) + return SelectInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectInput +// selectInputRequest writes a SelectInput request to a byte slice. +func selectInputRequest(c *xgb.Conn, DestinationWindow xproto.Window, Enable bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SHAPE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(DestinationWindow)) + b += 4 + + if Enable { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} diff --git a/vend/xgb/shm/shm.go b/vend/xgb/shm/shm.go new file mode 100644 index 0000000..732eb68 --- /dev/null +++ b/vend/xgb/shm/shm.go @@ -0,0 +1,945 @@ +// Package shm is the X client API for the MIT-SHM extension. +package shm + +// This file is automatically generated from shm.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the MIT-SHM extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 7, "MIT-SHM").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named MIT-SHM could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["MIT-SHM"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["MIT-SHM"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["MIT-SHM"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["MIT-SHM"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["MIT-SHM"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadSeg is the error number for a BadBadSeg. +const BadBadSeg = 0 + +type BadSegError xproto.ValueError + +// BadSegErrorNew constructs a BadSegError value that implements xgb.Error from a byte slice. +func BadSegErrorNew(buf []byte) xgb.Error { + v := BadSegError(xproto.ValueErrorNew(buf).(xproto.ValueError)) + v.NiceName = "BadSeg" + return v +} + +// SequenceId returns the sequence id attached to the BadBadSeg error. +// This is mostly used internally. +func (err BadSegError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadSeg error. If no bad value exists, 0 is returned. +func (err BadSegError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadSeg error. +func (err BadSegError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadBadSeg {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["MIT-SHM"][0] = BadSegErrorNew +} + +// Completion is the event number for a CompletionEvent. +const Completion = 0 + +type CompletionEvent struct { + Sequence uint16 + // padding: 1 bytes + Drawable xproto.Drawable + MinorEvent uint16 + MajorEvent byte + // padding: 1 bytes + Shmseg Seg + Offset uint32 +} + +// CompletionEventNew constructs a CompletionEvent value that implements xgb.Event from a byte slice. +func CompletionEventNew(buf []byte) xgb.Event { + v := CompletionEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Drawable = xproto.Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.MinorEvent = xgb.Get16(buf[b:]) + b += 2 + + v.MajorEvent = buf[b] + b += 1 + + b += 1 // padding + + v.Shmseg = Seg(xgb.Get32(buf[b:])) + b += 4 + + v.Offset = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Bytes writes a CompletionEvent value to a byte slice. +func (v CompletionEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put16(buf[b:], v.MinorEvent) + b += 2 + + buf[b] = v.MajorEvent + b += 1 + + b += 1 // padding + + xgb.Put32(buf[b:], uint32(v.Shmseg)) + b += 4 + + xgb.Put32(buf[b:], v.Offset) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the Completion event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v CompletionEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of CompletionEvent. +func (v CompletionEvent) String() string { + fieldVals := make([]string, 0, 7) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorEvent: %d", v.MinorEvent)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorEvent: %d", v.MajorEvent)) + fieldVals = append(fieldVals, xgb.Sprintf("Shmseg: %d", v.Shmseg)) + fieldVals = append(fieldVals, xgb.Sprintf("Offset: %d", v.Offset)) + return "Completion {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["MIT-SHM"][0] = CompletionEventNew +} + +type Seg uint32 + +func NewSegId(c *xgb.Conn) (Seg, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Seg(id), nil +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AttachCookie is a cookie used only for Attach requests. +type AttachCookie struct { + *xgb.Cookie +} + +// Attach sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Attach(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) AttachCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'Attach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(attachRequest(c, Shmseg, Shmid, ReadOnly), cookie) + return AttachCookie{cookie} +} + +// AttachChecked sends a checked request. +// If an error occurs, it can be retrieved using AttachCookie.Check() +func AttachChecked(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) AttachCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'Attach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(attachRequest(c, Shmseg, Shmid, ReadOnly), cookie) + return AttachCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AttachCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Attach +// attachRequest writes a Attach request to a byte slice. +func attachRequest(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + xgb.Put32(buf[b:], Shmid) + b += 4 + + if ReadOnly { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// AttachFdCookie is a cookie used only for AttachFd requests. +type AttachFdCookie struct { + *xgb.Cookie +} + +// AttachFd sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AttachFd(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie) + return AttachFdCookie{cookie} +} + +// AttachFdChecked sends a checked request. +// If an error occurs, it can be retrieved using AttachFdCookie.Check() +func AttachFdChecked(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie) + return AttachFdCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AttachFdCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for AttachFd +// attachFdRequest writes a AttachFd request to a byte slice. +func attachFdRequest(c *xgb.Conn, Shmseg Seg, ReadOnly bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + if ReadOnly { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// CreatePixmapCookie is a cookie used only for CreatePixmap requests. +type CreatePixmapCookie struct { + *xgb.Cookie +} + +// CreatePixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreatePixmap(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) CreatePixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createPixmapRequest(c, Pid, Drawable, Width, Height, Depth, Shmseg, Offset), cookie) + return CreatePixmapCookie{cookie} +} + +// CreatePixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using CreatePixmapCookie.Check() +func CreatePixmapChecked(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) CreatePixmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createPixmapRequest(c, Pid, Drawable, Width, Height, Depth, Shmseg, Offset), cookie) + return CreatePixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreatePixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreatePixmap +// createPixmapRequest writes a CreatePixmap request to a byte slice. +func createPixmapRequest(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) []byte { + size := 28 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Pid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + buf[b] = Depth + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + xgb.Put32(buf[b:], Offset) + b += 4 + + return buf +} + +// CreateSegmentCookie is a cookie used only for CreateSegment requests. +type CreateSegmentCookie struct { + *xgb.Cookie +} + +// CreateSegment sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateSegmentCookie.Reply() +func CreateSegment(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie) + return CreateSegmentCookie{cookie} +} + +// CreateSegmentUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateSegmentUnchecked(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie) + return CreateSegmentCookie{cookie} +} + +// CreateSegmentReply represents the data returned from a CreateSegment request. +type CreateSegmentReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Nfd byte + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a CreateSegment request. +func (cook CreateSegmentCookie) Reply() (*CreateSegmentReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createSegmentReply(buf), nil +} + +// createSegmentReply reads a byte slice into a CreateSegmentReply value. +func createSegmentReply(buf []byte) *CreateSegmentReply { + v := new(CreateSegmentReply) + b := 1 // skip reply determinant + + v.Nfd = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for CreateSegment +// createSegmentRequest writes a CreateSegment request to a byte slice. +func createSegmentRequest(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + xgb.Put32(buf[b:], Size) + b += 4 + + if ReadOnly { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// DetachCookie is a cookie used only for Detach requests. +type DetachCookie struct { + *xgb.Cookie +} + +// Detach sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Detach(c *xgb.Conn, Shmseg Seg) DetachCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'Detach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(detachRequest(c, Shmseg), cookie) + return DetachCookie{cookie} +} + +// DetachChecked sends a checked request. +// If an error occurs, it can be retrieved using DetachCookie.Check() +func DetachChecked(c *xgb.Conn, Shmseg Seg) DetachCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'Detach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(detachRequest(c, Shmseg), cookie) + return DetachCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DetachCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Detach +// detachRequest writes a Detach request to a byte slice. +func detachRequest(c *xgb.Conn, Shmseg Seg) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + return buf +} + +// GetImageCookie is a cookie used only for GetImage requests. +type GetImageCookie struct { + *xgb.Cookie +} + +// GetImage sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetImageCookie.Reply() +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 { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'GetImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getImageRequest(c, Drawable, X, Y, Width, Height, PlaneMask, Format, Shmseg, Offset), cookie) + return GetImageCookie{cookie} +} + +// GetImageUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +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 { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'GetImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getImageRequest(c, Drawable, X, Y, Width, Height, PlaneMask, Format, Shmseg, Offset), cookie) + return GetImageCookie{cookie} +} + +// GetImageReply represents the data returned from a GetImage request. +type GetImageReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Depth byte + Visual xproto.Visualid + Size uint32 +} + +// Reply blocks and returns the reply data for a GetImage request. +func (cook GetImageCookie) Reply() (*GetImageReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getImageReply(buf), nil +} + +// getImageReply reads a byte slice into a GetImageReply value. +func getImageReply(buf []byte) *GetImageReply { + v := new(GetImageReply) + b := 1 // skip reply determinant + + v.Depth = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Visual = xproto.Visualid(xgb.Get32(buf[b:])) + b += 4 + + v.Size = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetImage +// getImageRequest writes a GetImage request to a byte slice. +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 { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put32(buf[b:], PlaneMask) + b += 4 + + buf[b] = Format + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + xgb.Put32(buf[b:], Offset) + b += 4 + + return buf +} + +// PutImageCookie is a cookie used only for PutImage requests. +type PutImageCookie struct { + *xgb.Cookie +} + +// PutImage sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +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 { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'PutImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(putImageRequest(c, Drawable, Gc, TotalWidth, TotalHeight, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, Depth, Format, SendEvent, Shmseg, Offset), cookie) + return PutImageCookie{cookie} +} + +// PutImageChecked sends a checked request. +// If an error occurs, it can be retrieved using PutImageCookie.Check() +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 { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'PutImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(putImageRequest(c, Drawable, Gc, TotalWidth, TotalHeight, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, Depth, Format, SendEvent, Shmseg, Offset), cookie) + return PutImageCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PutImageCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PutImage +// putImageRequest writes a PutImage request to a byte slice. +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 { + size := 40 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], TotalWidth) + b += 2 + + xgb.Put16(buf[b:], TotalHeight) + b += 2 + + xgb.Put16(buf[b:], SrcX) + b += 2 + + xgb.Put16(buf[b:], SrcY) + b += 2 + + xgb.Put16(buf[b:], SrcWidth) + b += 2 + + xgb.Put16(buf[b:], SrcHeight) + b += 2 + + xgb.Put16(buf[b:], uint16(DstX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstY)) + b += 2 + + buf[b] = Depth + b += 1 + + buf[b] = Format + b += 1 + + buf[b] = SendEvent + b += 1 + + b += 1 // padding + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + xgb.Put32(buf[b:], Offset) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["MIT-SHM"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + SharedPixmaps bool + MajorVersion uint16 + MinorVersion uint16 + Uid uint16 + Gid uint16 + PixmapFormat byte + // padding: 15 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.SharedPixmaps = true + } else { + v.SharedPixmaps = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.Uid = xgb.Get16(buf[b:]) + b += 2 + + v.Gid = xgb.Get16(buf[b:]) + b += 2 + + v.PixmapFormat = buf[b] + b += 1 + + b += 15 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["MIT-SHM"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} diff --git a/vend/xgb/sync.go b/vend/xgb/sync.go new file mode 100644 index 0000000..59d0de1 --- /dev/null +++ b/vend/xgb/sync.go @@ -0,0 +1,29 @@ +package xgb + +// Sync sends a round trip request and waits for the response. +// This forces all pending cookies to be dealt with. +// You actually shouldn't need to use this like you might with Xlib. Namely, +// buffers are automatically flushed using Go's channels and round trip requests +// are forced where appropriate automatically. +func (c *Conn) Sync() { + cookie := c.NewCookie(true, true) + c.NewRequest(c.getInputFocusRequest(), cookie) + cookie.Reply() // wait for the buffer to clear +} + +// getInputFocusRequest writes the raw bytes to a buffer. +// It is duplicated from xproto/xproto.go. +func (c *Conn) getInputFocusRequest() []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 43 // request opcode + b += 1 + + b += 1 // padding + Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} diff --git a/vend/xgb/testingTools.go b/vend/xgb/testingTools.go new file mode 100644 index 0000000..2f73031 --- /dev/null +++ b/vend/xgb/testingTools.go @@ -0,0 +1,426 @@ +package xgb + +import ( + "bytes" + "errors" + "io" + "net" + "regexp" + "runtime" + "strconv" + "strings" + "testing" + "time" +) + +// Leaks monitor + +type goroutine struct { + id int + name string + stack []byte +} + +type leaks struct { + name string + goroutines map[int]goroutine + report []*leaks +} + +func leaksMonitor(name string, monitors ...*leaks) *leaks { + return &leaks{ + name, + leaks{}.collectGoroutines(), + monitors, + } +} + +// ispired by https://golang.org/src/runtime/debug/stack.go?s=587:606#L21 +// stack returns a formatted stack trace of all goroutines. +// It calls runtime.Stack with a large enough buffer to capture the entire trace. +func (_ leaks) stack() []byte { + buf := make([]byte, 1024) + for { + n := runtime.Stack(buf, true) + if n < len(buf) { + return buf[:n] + } + buf = make([]byte, 2*len(buf)) + } +} + +func (l leaks) collectGoroutines() map[int]goroutine { + res := make(map[int]goroutine) + stacks := bytes.Split(l.stack(), []byte{'\n', '\n'}) + + regexpId := regexp.MustCompile(`^\s*goroutine\s*(\d+)`) + for _, st := range stacks { + lines := bytes.Split(st, []byte{'\n'}) + if len(lines) < 2 { + panic("routine stach has less tnan two lines: " + string(st)) + } + + idMatches := regexpId.FindSubmatch(lines[0]) + if len(idMatches) < 2 { + panic("no id found in goroutine stack's first line: " + string(lines[0])) + } + id, err := strconv.Atoi(string(idMatches[1])) + if err != nil { + panic("converting goroutine id to number error: " + err.Error()) + } + if _, ok := res[id]; ok { + panic("2 goroutines with same id: " + strconv.Itoa(id)) + } + name := strings.TrimSpace(string(lines[1])) + + //filter out our stack routine + if strings.Contains(name, "xgb.leaks.stack") { + continue + } + + res[id] = goroutine{id, name, st} + } + return res +} + +func (l leaks) leakingGoroutines() []goroutine { + goroutines := l.collectGoroutines() + res := []goroutine{} + for id, gr := range goroutines { + if _, ok := l.goroutines[id]; ok { + continue + } + res = append(res, gr) + } + return res +} +func (l leaks) checkTesting(t *testing.T) { + if len(l.leakingGoroutines()) == 0 { + return + } + leakTimeout := 10 * time.Millisecond + time.Sleep(leakTimeout) + //t.Logf("possible goroutine leakage, waiting %v", leakTimeout) + grs := l.leakingGoroutines() + for _, gr := range grs { + t.Errorf("%s: %s is leaking", l.name, gr.name) + //t.Errorf("%s: %s is leaking\n%v", l.name, gr.name, string(gr.stack)) + } + for _, rl := range l.report { + rl.ignoreLeak(grs...) + } +} +func (l *leaks) ignoreLeak(grs ...goroutine) { + for _, gr := range grs { + l.goroutines[gr.id] = gr + } +} + +// dummy net.Conn + +type dAddr struct { + s string +} + +func (_ dAddr) Network() string { return "dummy" } +func (a dAddr) String() string { return a.s } + +var ( + dNCErrNotImplemented = errors.New("command not implemented") + dNCErrClosed = errors.New("server closed") + dNCErrWrite = errors.New("server write failed") + dNCErrRead = errors.New("server read failed") + dNCErrResponse = errors.New("server response error") +) + +type dNCIoResult struct { + n int + err error +} +type dNCIo struct { + b []byte + result chan dNCIoResult +} + +type dNCCWriteLock struct{} +type dNCCWriteUnlock struct{} +type dNCCWriteError struct{} +type dNCCWriteSuccess struct{} +type dNCCReadLock struct{} +type dNCCReadUnlock struct{} +type dNCCReadError struct{} +type dNCCReadSuccess struct{} + +// dummy net.Conn interface. Needs to be constructed via newDummyNetConn([...]) function. +type dNC struct { + reply func([]byte) []byte + addr dAddr + in, out chan dNCIo + control chan interface{} + done chan struct{} +} + +// Results running dummy server, satisfying net.Conn interface for test purposes. +// 'name' parameter will be returned via (*dNC).Local/RemoteAddr().String() +// 'reply' parameter function will be runned only on successful (*dNC).Write(b) with 'b' as parameter to 'reply'. The result will be stored in internal buffer and can be retrieved later via (*dNC).Read([...]) method. +// It is users responsibility to stop and clean up resources with (*dNC).Close, if not needed anymore. +// By default, the (*dNC).Write([...]) and (*dNC).Read([...]) methods are unlocked and will not result in error. +//TODO make (*dNC).SetDeadline, (*dNC).SetReadDeadline, (*dNC).SetWriteDeadline work proprely. +func newDummyNetConn(name string, reply func([]byte) []byte) *dNC { + + s := &dNC{ + reply, + dAddr{name}, + make(chan dNCIo), make(chan dNCIo), + make(chan interface{}), + make(chan struct{}), + } + + in, out := s.in, chan dNCIo(nil) + buf := &bytes.Buffer{} + errorRead, errorWrite := false, false + lockRead := false + + go func() { + defer close(s.done) + for { + select { + case dxsio := <-in: + if errorWrite { + dxsio.result <- dNCIoResult{0, dNCErrWrite} + break + } + + response := s.reply(dxsio.b) + + buf.Write(response) + dxsio.result <- dNCIoResult{len(dxsio.b), nil} + + if !lockRead && buf.Len() > 0 && out == nil { + out = s.out + } + case dxsio := <-out: + if errorRead { + dxsio.result <- dNCIoResult{0, dNCErrRead} + break + } + + n, err := buf.Read(dxsio.b) + dxsio.result <- dNCIoResult{n, err} + + if buf.Len() == 0 { + out = nil + } + case ci := <-s.control: + if ci == nil { + return + } + switch ci.(type) { + case dNCCWriteLock: + in = nil + case dNCCWriteUnlock: + in = s.in + case dNCCWriteError: + errorWrite = true + case dNCCWriteSuccess: + errorWrite = false + case dNCCReadLock: + out = nil + lockRead = true + case dNCCReadUnlock: + lockRead = false + if buf.Len() > 0 && out == nil { + out = s.out + } + case dNCCReadError: + errorRead = true + case dNCCReadSuccess: + errorRead = false + default: + } + } + } + }() + return s +} + +// Shuts down dummy net.Conn server. Every blocking or future method calls will do nothing and result in error. +// Result will be dNCErrClosed if server was allready closed. +// Server can not be unclosed. +func (s *dNC) Close() error { + select { + case s.control <- nil: + <-s.done + return nil + case <-s.done: + } + return dNCErrClosed +} + +// Performs a write action to server. +// If not locked by (*dNC).WriteLock, it results in error or success. If locked, this method will block until unlocked, or closed. +// +// This method can be set to result in error or success, via (*dNC).WriteError() or (*dNC).WriteSuccess() methods. +// +// If setted to result in error, the 'reply' function will NOT be called and internal buffer will NOT increasethe. +// Result will be (0, dNCErrWrite). +// +// If setted to result in success, the 'reply' function will be called and its result will be writen to internal buffer. +// If there is something in the internal buffer, the (*dNC).Read([...]) will be unblocked (if not previously locked with (*dNC).ReadLock). +// Result will be (len(b), nil) +// +// If server was closed previously, result will be (0, dNCErrClosed). +func (s *dNC) Write(b []byte) (int, error) { + resChan := make(chan dNCIoResult) + select { + case s.in <- dNCIo{b, resChan}: + res := <-resChan + return res.n, res.err + case <-s.done: + } + return 0, dNCErrClosed +} + +// Performs a read action from server. +// If locked by (*dNC).ReadLock(), this method will block until unlocked with (*dNC).ReadUnlock(), or server closes. +// +// If not locked, this method can be setted to result imidiatly in error, will block if internal buffer is empty or will perform an read operation from internal buffer. +// +// If setted to result in error via (*dNC).ReadError(), the result will be (0, dNCErrWrite). +// +// If not locked and not setted to result in error via (*dNC).ReadSuccess(), this method will block until internall buffer is not empty, than it returns the result of the buffer read operation via (*bytes.Buffer).Read([...]). +// If the internal buffer is empty after this method, all follwing (*dNC).Read([...]), requests will block until internall buffer is filled after successful write requests. +// +// If server was closed previously, result will be (0, io.EOF). +func (s *dNC) Read(b []byte) (int, error) { + resChan := make(chan dNCIoResult) + select { + case s.out <- dNCIo{b, resChan}: + res := <-resChan + return res.n, res.err + case <-s.done: + } + return 0, io.EOF +} +func (s *dNC) LocalAddr() net.Addr { return s.addr } +func (s *dNC) RemoteAddr() net.Addr { return s.addr } +func (s *dNC) SetDeadline(t time.Time) error { return dNCErrNotImplemented } +func (s *dNC) SetReadDeadline(t time.Time) error { return dNCErrNotImplemented } +func (s *dNC) SetWriteDeadline(t time.Time) error { return dNCErrNotImplemented } + +func (s *dNC) Control(i interface{}) error { + select { + case s.control <- i: + return nil + case <-s.done: + } + return dNCErrClosed +} + +// Locks writing. All write requests will be blocked until write is unlocked with (*dNC).WriteUnlock, or server closes. +func (s *dNC) WriteLock() error { + return s.Control(dNCCWriteLock{}) +} + +// Unlocks writing. All blocked write requests until now will be accepted. +func (s *dNC) WriteUnlock() error { + return s.Control(dNCCWriteUnlock{}) +} + +// Unlocks writing and makes (*dNC).Write to result (0, dNCErrWrite). +func (s *dNC) WriteError() error { + if err := s.WriteUnlock(); err != nil { + return err + } + return s.Control(dNCCWriteError{}) +} + +// Unlocks writing and makes (*dNC).Write([...]) not result in error. See (*dNC).Write for details. +func (s *dNC) WriteSuccess() error { + if err := s.WriteUnlock(); err != nil { + return err + } + return s.Control(dNCCWriteSuccess{}) +} + +// Locks reading. All read requests will be blocked until read is unlocked with (*dNC).ReadUnlock, or server closes. +// (*dNC).Read([...]) wil block even after successful write. +func (s *dNC) ReadLock() error { + return s.Control(dNCCReadLock{}) +} + +// Unlocks reading. If the internall buffer is not empty, next read will not block. +func (s *dNC) ReadUnlock() error { + return s.Control(dNCCReadUnlock{}) +} + +// Unlocks read and makes every blocked and following (*dNC).Read([...]) imidiatly result in error. See (*dNC).Read for details. +func (s *dNC) ReadError() error { + if err := s.ReadUnlock(); err != nil { + return err + } + return s.Control(dNCCReadError{}) +} + +// Unlocks read and makes every blocked and following (*dNC).Read([...]) requests be handled, if according to internal buffer. See (*dNC).Read for details. +func (s *dNC) ReadSuccess() error { + if err := s.ReadUnlock(); err != nil { + return err + } + return s.Control(dNCCReadSuccess{}) +} + +// dummy X server replier for dummy net.Conn + +type dXSEvent struct{} + +func (_ dXSEvent) Bytes() []byte { return nil } +func (_ dXSEvent) String() string { return "dummy X server event" } + +type dXSError struct { + seqId uint16 +} + +func (e dXSError) SequenceId() uint16 { return e.seqId } +func (_ dXSError) BadId() uint32 { return 0 } +func (_ dXSError) Error() string { return "dummy X server error reply" } + +func newDummyXServerReplier() func([]byte) []byte { + // register xgb error & event replies + NewErrorFuncs[255] = func(buf []byte) Error { + return dXSError{Get16(buf[2:])} + } + NewEventFuncs[128&127] = func(buf []byte) Event { + return dXSEvent{} + } + + // sequence number generator + seqId := uint16(1) + incrementSequenceId := func() { + // this has to be the same algorithm as in (*Conn).generateSeqIds + if seqId == uint16((1<<16)-1) { + seqId = 0 + } else { + seqId++ + } + } + return func(request []byte) []byte { + res := make([]byte, 32) + switch string(request) { + case "event": + res[0] = 128 + return res + case "error": + res[0] = 0 // error + res[1] = 255 // error function + default: + res[0] = 1 // reply + } + Put16(res[2:], seqId) // sequence number + incrementSequenceId() + if string(request) == "noreply" { + return nil + } + return res + } +} diff --git a/vend/xgb/testingTools_test.go b/vend/xgb/testingTools_test.go new file mode 100644 index 0000000..518b326 --- /dev/null +++ b/vend/xgb/testingTools_test.go @@ -0,0 +1,350 @@ +package xgb + +import ( + "bytes" + "errors" + "fmt" + "io" + "reflect" + "sync" + "testing" + "time" +) + +func TestLeaks(t *testing.T) { + lm := leaksMonitor("lm") + if lgrs := lm.leakingGoroutines(); len(lgrs) != 0 { + t.Errorf("leakingGoroutines returned %d leaking goroutines, want 0", len(lgrs)) + } + + done := make(chan struct{}) + wg := &sync.WaitGroup{} + + wg.Add(1) + go func() { + <-done + wg.Done() + }() + + if lgrs := lm.leakingGoroutines(); len(lgrs) != 1 { + t.Errorf("leakingGoroutines returned %d leaking goroutines, want 1", len(lgrs)) + } + + wg.Add(1) + go func() { + <-done + wg.Done() + }() + + if lgrs := lm.leakingGoroutines(); len(lgrs) != 2 { + t.Errorf("leakingGoroutines returned %d leaking goroutines, want 2", len(lgrs)) + } + + close(done) + wg.Wait() + + if lgrs := lm.leakingGoroutines(); len(lgrs) != 0 { + t.Errorf("leakingGoroutines returned %d leaking goroutines, want 0", len(lgrs)) + } + + lm.checkTesting(t) + //TODO multiple leak monitors with report ignore tests +} + +func TestDummyNetConn(t *testing.T) { + ioStatesPairGenerator := func(writeStates, readStates []string) []func() (*dNC, error) { + writeSetters := map[string]func(*dNC) error{ + "lock": (*dNC).WriteLock, + "error": (*dNC).WriteError, + "success": (*dNC).WriteSuccess, + } + readSetters := map[string]func(*dNC) error{ + "lock": (*dNC).ReadLock, + "error": (*dNC).ReadError, + "success": (*dNC).ReadSuccess, + } + + res := []func() (*dNC, error){} + for _, writeState := range writeStates { + writeState, writeSetter := writeState, writeSetters[writeState] + if writeSetter == nil { + panic("unknown write state: " + writeState) + continue + } + for _, readState := range readStates { + readState, readSetter := readState, readSetters[readState] + if readSetter == nil { + panic("unknown read state: " + readState) + continue + } + res = append(res, func() (*dNC, error) { + + // loopback server + s := newDummyNetConn("w:"+writeState+";r:"+readState, func(b []byte) []byte { return b }) + + if err := readSetter(s); err != nil { + s.Close() + return nil, errors.New("set read " + readState + " error: " + err.Error()) + } + + if err := writeSetter(s); err != nil { + s.Close() + return nil, errors.New("set write " + writeState + " error: " + err.Error()) + } + + return s, nil + }) + } + } + return res + } + + timeout := 10 * time.Millisecond + wantResponse := func(action func(*dNC) error, want, block error) func(*dNC) error { + return func(s *dNC) error { + actionResult := make(chan error) + timedOut := make(chan struct{}) + go func() { + err := action(s) + select { + case <-timedOut: + if err != block { + t.Errorf("after unblocking, action result=%v, want %v", err, block) + } + case actionResult <- err: + } + }() + select { + case err := <-actionResult: + if err != want { + return errors.New(fmt.Sprintf("action result=%v, want %v", err, want)) + } + case <-time.After(timeout): + close(timedOut) + return errors.New(fmt.Sprintf("action did not respond for %v, result want %v", timeout, want)) + } + return nil + } + } + wantBlock := func(action func(*dNC) error, unblock error) func(*dNC) error { + return func(s *dNC) error { + actionResult := make(chan error) + timedOut := make(chan struct{}) + go func() { + err := action(s) + select { + case <-timedOut: + if err != unblock { + t.Errorf("after unblocking, action result=%v, want %v", err, unblock) + } + case actionResult <- err: + } + }() + select { + case err := <-actionResult: + return errors.New(fmt.Sprintf("action result=%v, want to be blocked", err)) + case <-time.After(timeout): + close(timedOut) + } + return nil + } + } + write := func(b string) func(*dNC) error { + return func(s *dNC) error { + n, err := s.Write([]byte(b)) + if err == nil && n != len(b) { + return errors.New("Write returned nil error, but not everything was written") + } + return err + } + } + read := func(b string) func(*dNC) error { + return func(s *dNC) error { + r := make([]byte, len(b)) + n, err := s.Read(r) + if err == nil { + if n != len(b) { + return errors.New("Read returned nil error, but not everything was read") + } + if !reflect.DeepEqual(r, []byte(b)) { + return errors.New("Read=\"" + string(r) + "\", want \"" + string(b) + "\"") + } + } + return err + } + } + + testCases := []struct { + description string + servers []func() (*dNC, error) + actions []func(*dNC) error // actions per server + }{ + {"close,close", + ioStatesPairGenerator( + []string{"lock", "error", "success"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantResponse((*dNC).Close, nil, dNCErrClosed), + wantResponse((*dNC).Close, dNCErrClosed, dNCErrClosed), + }, + }, + {"write,close,write", + ioStatesPairGenerator( + []string{"lock"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantBlock(write(""), dNCErrClosed), + wantResponse((*dNC).Close, nil, dNCErrClosed), + wantResponse(write(""), dNCErrClosed, dNCErrClosed), + }, + }, + {"write,close,write", + ioStatesPairGenerator( + []string{"error"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantResponse(write(""), dNCErrWrite, dNCErrClosed), + wantResponse((*dNC).Close, nil, dNCErrClosed), + wantResponse(write(""), dNCErrClosed, dNCErrClosed), + }, + }, + {"write,close,write", + ioStatesPairGenerator( + []string{"success"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantResponse(write(""), nil, dNCErrClosed), + wantResponse((*dNC).Close, nil, dNCErrClosed), + wantResponse(write(""), dNCErrClosed, dNCErrClosed), + }, + }, + {"read,close,read", + ioStatesPairGenerator( + []string{"lock", "error", "success"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantBlock(read(""), io.EOF), + wantResponse((*dNC).Close, nil, dNCErrClosed), + wantResponse(read(""), io.EOF, io.EOF), + }, + }, + {"write,read", + ioStatesPairGenerator( + []string{"lock"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantBlock(write("1"), dNCErrClosed), + wantBlock(read("1"), io.EOF), + }, + }, + {"write,read", + ioStatesPairGenerator( + []string{"error"}, + []string{"lock", "error", "success"}, + ), + []func(*dNC) error{ + wantResponse(write("1"), dNCErrWrite, dNCErrClosed), + wantBlock(read("1"), io.EOF), + }, + }, + {"write,read", + ioStatesPairGenerator( + []string{"success"}, + []string{"lock"}, + ), + []func(*dNC) error{ + wantResponse(write("1"), nil, dNCErrClosed), + wantBlock(read("1"), io.EOF), + }, + }, + {"write,read", + ioStatesPairGenerator( + []string{"success"}, + []string{"error"}, + ), + []func(*dNC) error{ + wantResponse(write("1"), nil, dNCErrClosed), + wantResponse(read("1"), dNCErrRead, io.EOF), + }, + }, + {"write,read", + ioStatesPairGenerator( + []string{"success"}, + []string{"success"}, + ), + []func(*dNC) error{ + wantResponse(write("1"), nil, dNCErrClosed), + wantResponse(read("1"), nil, io.EOF), + }, + }, + } + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + defer leaksMonitor(tc.description).checkTesting(t) + + for _, server := range tc.servers { + s, err := server() + if err != nil { + t.Error(err) + continue + } + if s == nil { + t.Error("nil server in testcase") + continue + } + + t.Run(s.LocalAddr().String(), func(t *testing.T) { + defer leaksMonitor(s.LocalAddr().String()).checkTesting(t) + for _, action := range tc.actions { + if err := action(s); err != nil { + t.Error(err) + break + } + } + s.Close() + }) + } + }) + } +} + +func TestDummyXServerReplier(t *testing.T) { + testCases := [][][2][]byte{ + { + [2][]byte{[]byte("reply"), []byte{1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("eply"), []byte{1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("ply"), []byte{1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("event"), []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("ly"), []byte{1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("y"), []byte{1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte(""), []byte{1, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("event"), []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("reply"), []byte{1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("error"), []byte{0, 255, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("ply"), []byte{1, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("event"), []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("ly"), []byte{1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("noreply"), nil}, + [2][]byte{[]byte("error"), []byte{0, 255, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + [2][]byte{[]byte("noreply"), nil}, + [2][]byte{[]byte(""), []byte{1, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + }, + } + + for tci, tc := range testCases { + replier := newDummyXServerReplier() + for ai, ioPair := range tc { + in, want := ioPair[0], ioPair[1] + if out := replier(in); !bytes.Equal(out, want) { + t.Errorf("testCase %d, action %d, replier(%s) = %v, want %v", tci, ai, string(in), out, want) + break + } + } + } +} diff --git a/vend/xgb/xcmisc/xcmisc.go b/vend/xgb/xcmisc/xcmisc.go new file mode 100644 index 0000000..93dd20f --- /dev/null +++ b/vend/xgb/xcmisc/xcmisc.go @@ -0,0 +1,361 @@ +// Package xcmisc is the X client API for the XC-MISC extension. +package xcmisc + +// This file is automatically generated from xc_misc.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XC-MISC extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 7, "XC-MISC").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XC-MISC could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XC-MISC"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XC-MISC"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XC-MISC"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XC-MISC"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XC-MISC"] = make(map[int]xgb.NewErrorFun) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// GetVersionCookie is a cookie used only for GetVersion requests. +type GetVersionCookie struct { + *xgb.Cookie +} + +// GetVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetVersionCookie.Reply() +func GetVersion(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) GetVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XC-MISC"]; !ok { + panic("Cannot issue request 'GetVersion' using the uninitialized extension 'XC-MISC'. xcmisc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return GetVersionCookie{cookie} +} + +// GetVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) GetVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XC-MISC"]; !ok { + panic("Cannot issue request 'GetVersion' using the uninitialized extension 'XC-MISC'. xcmisc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return GetVersionCookie{cookie} +} + +// GetVersionReply represents the data returned from a GetVersion request. +type GetVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ServerMajorVersion uint16 + ServerMinorVersion uint16 +} + +// Reply blocks and returns the reply data for a GetVersion request. +func (cook GetVersionCookie) Reply() (*GetVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getVersionReply(buf), nil +} + +// getVersionReply reads a byte slice into a GetVersionReply value. +func getVersionReply(buf []byte) *GetVersionReply { + v := new(GetVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ServerMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ServerMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for GetVersion +// getVersionRequest writes a GetVersion request to a byte slice. +func getVersionRequest(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XC-MISC"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], ClientMajorVersion) + b += 2 + + xgb.Put16(buf[b:], ClientMinorVersion) + b += 2 + + return buf +} + +// GetXIDListCookie is a cookie used only for GetXIDList requests. +type GetXIDListCookie struct { + *xgb.Cookie +} + +// GetXIDList sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetXIDListCookie.Reply() +func GetXIDList(c *xgb.Conn, Count uint32) GetXIDListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XC-MISC"]; !ok { + panic("Cannot issue request 'GetXIDList' using the uninitialized extension 'XC-MISC'. xcmisc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getXIDListRequest(c, Count), cookie) + return GetXIDListCookie{cookie} +} + +// GetXIDListUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetXIDListUnchecked(c *xgb.Conn, Count uint32) GetXIDListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XC-MISC"]; !ok { + panic("Cannot issue request 'GetXIDList' using the uninitialized extension 'XC-MISC'. xcmisc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getXIDListRequest(c, Count), cookie) + return GetXIDListCookie{cookie} +} + +// GetXIDListReply represents the data returned from a GetXIDList request. +type GetXIDListReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + IdsLen uint32 + // padding: 20 bytes + Ids []uint32 // size: xgb.Pad((int(IdsLen) * 4)) +} + +// Reply blocks and returns the reply data for a GetXIDList request. +func (cook GetXIDListCookie) Reply() (*GetXIDListReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getXIDListReply(buf), nil +} + +// getXIDListReply reads a byte slice into a GetXIDListReply value. +func getXIDListReply(buf []byte) *GetXIDListReply { + v := new(GetXIDListReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.IdsLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Ids = make([]uint32, v.IdsLen) + for i := 0; i < int(v.IdsLen); i++ { + v.Ids[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetXIDList +// getXIDListRequest writes a GetXIDList request to a byte slice. +func getXIDListRequest(c *xgb.Conn, Count uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XC-MISC"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Count) + b += 4 + + return buf +} + +// GetXIDRangeCookie is a cookie used only for GetXIDRange requests. +type GetXIDRangeCookie struct { + *xgb.Cookie +} + +// GetXIDRange sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetXIDRangeCookie.Reply() +func GetXIDRange(c *xgb.Conn) GetXIDRangeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XC-MISC"]; !ok { + panic("Cannot issue request 'GetXIDRange' using the uninitialized extension 'XC-MISC'. xcmisc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getXIDRangeRequest(c), cookie) + return GetXIDRangeCookie{cookie} +} + +// GetXIDRangeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetXIDRangeUnchecked(c *xgb.Conn) GetXIDRangeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XC-MISC"]; !ok { + panic("Cannot issue request 'GetXIDRange' using the uninitialized extension 'XC-MISC'. xcmisc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getXIDRangeRequest(c), cookie) + return GetXIDRangeCookie{cookie} +} + +// GetXIDRangeReply represents the data returned from a GetXIDRange request. +type GetXIDRangeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + StartId uint32 + Count uint32 +} + +// Reply blocks and returns the reply data for a GetXIDRange request. +func (cook GetXIDRangeCookie) Reply() (*GetXIDRangeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getXIDRangeReply(buf), nil +} + +// getXIDRangeReply reads a byte slice into a GetXIDRangeReply value. +func getXIDRangeReply(buf []byte) *GetXIDRangeReply { + v := new(GetXIDRangeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.StartId = xgb.Get32(buf[b:]) + b += 4 + + v.Count = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetXIDRange +// getXIDRangeRequest writes a GetXIDRange request to a byte slice. +func getXIDRangeRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XC-MISC"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} diff --git a/vend/xgb/xevie/xevie.go b/vend/xgb/xevie/xevie.go new file mode 100644 index 0000000..f0ddd31 --- /dev/null +++ b/vend/xgb/xevie/xevie.go @@ -0,0 +1,595 @@ +// Package xevie is the X client API for the XEVIE extension. +package xevie + +// This file is automatically generated from xevie.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XEVIE extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 5, "XEVIE").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XEVIE could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XEVIE"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XEVIE"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XEVIE"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XEVIE"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XEVIE"] = make(map[int]xgb.NewErrorFun) +} + +const ( + DatatypeUnmodified = 0 + DatatypeModified = 1 +) + +type Event struct { + // padding: 32 bytes +} + +// EventRead reads a byte slice into a Event value. +func EventRead(buf []byte, v *Event) int { + b := 0 + + b += 32 // padding + + return b +} + +// EventReadList reads a byte slice into a list of Event values. +func EventReadList(buf []byte, dest []Event) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Event{} + b += EventRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Event value to a byte slice. +func (v Event) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + b += 32 // padding + + return buf[:b] +} + +// EventListBytes writes a list of Event values to a byte slice. +func EventListBytes(buf []byte, list []Event) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// EndCookie is a cookie used only for End requests. +type EndCookie struct { + *xgb.Cookie +} + +// End sends a checked request. +// If an error occurs, it will be returned with the reply by calling EndCookie.Reply() +func End(c *xgb.Conn, Cmap uint32) EndCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'End' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(endRequest(c, Cmap), cookie) + return EndCookie{cookie} +} + +// EndUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func EndUnchecked(c *xgb.Conn, Cmap uint32) EndCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'End' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(endRequest(c, Cmap), cookie) + return EndCookie{cookie} +} + +// EndReply represents the data returned from a End request. +type EndReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a End request. +func (cook EndCookie) Reply() (*EndReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return endReply(buf), nil +} + +// endReply reads a byte slice into a EndReply value. +func endReply(buf []byte) *EndReply { + v := new(EndReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for End +// endRequest writes a End request to a byte slice. +func endRequest(c *xgb.Conn, Cmap uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XEVIE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Cmap) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ServerMajorVersion uint16 + ServerMinorVersion uint16 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ServerMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ServerMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + b += 20 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint16, ClientMinorVersion uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XEVIE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], ClientMajorVersion) + b += 2 + + xgb.Put16(buf[b:], ClientMinorVersion) + b += 2 + + return buf +} + +// SelectInputCookie is a cookie used only for SelectInput requests. +type SelectInputCookie struct { + *xgb.Cookie +} + +// SelectInput sends a checked request. +// If an error occurs, it will be returned with the reply by calling SelectInputCookie.Reply() +func SelectInput(c *xgb.Conn, EventMask uint32) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(selectInputRequest(c, EventMask), cookie) + return SelectInputCookie{cookie} +} + +// SelectInputUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectInputUnchecked(c *xgb.Conn, EventMask uint32) SelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'SelectInput' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(selectInputRequest(c, EventMask), cookie) + return SelectInputCookie{cookie} +} + +// SelectInputReply represents the data returned from a SelectInput request. +type SelectInputReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a SelectInput request. +func (cook SelectInputCookie) Reply() (*SelectInputReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return selectInputReply(buf), nil +} + +// selectInputReply reads a byte slice into a SelectInputReply value. +func selectInputReply(buf []byte) *SelectInputReply { + v := new(SelectInputReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for SelectInput +// selectInputRequest writes a SelectInput request to a byte slice. +func selectInputRequest(c *xgb.Conn, EventMask uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XEVIE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], EventMask) + b += 4 + + return buf +} + +// SendCookie is a cookie used only for Send requests. +type SendCookie struct { + *xgb.Cookie +} + +// Send sends a checked request. +// If an error occurs, it will be returned with the reply by calling SendCookie.Reply() +func Send(c *xgb.Conn, Event Event, DataType uint32) SendCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'Send' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(sendRequest(c, Event, DataType), cookie) + return SendCookie{cookie} +} + +// SendUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SendUnchecked(c *xgb.Conn, Event Event, DataType uint32) SendCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'Send' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(sendRequest(c, Event, DataType), cookie) + return SendCookie{cookie} +} + +// SendReply represents the data returned from a Send request. +type SendReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a Send request. +func (cook SendCookie) Reply() (*SendReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return sendReply(buf), nil +} + +// sendReply reads a byte slice into a SendReply value. +func sendReply(buf []byte) *SendReply { + v := new(SendReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for Send +// sendRequest writes a Send request to a byte slice. +func sendRequest(c *xgb.Conn, Event Event, DataType uint32) []byte { + size := 104 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XEVIE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + { + structBytes := Event.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], DataType) + b += 4 + + b += 64 // padding + + return buf +} + +// StartCookie is a cookie used only for Start requests. +type StartCookie struct { + *xgb.Cookie +} + +// Start sends a checked request. +// If an error occurs, it will be returned with the reply by calling StartCookie.Reply() +func Start(c *xgb.Conn, Screen uint32) StartCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'Start' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(startRequest(c, Screen), cookie) + return StartCookie{cookie} +} + +// StartUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func StartUnchecked(c *xgb.Conn, Screen uint32) StartCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XEVIE"]; !ok { + panic("Cannot issue request 'Start' using the uninitialized extension 'XEVIE'. xevie.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(startRequest(c, Screen), cookie) + return StartCookie{cookie} +} + +// StartReply represents the data returned from a Start request. +type StartReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a Start request. +func (cook StartCookie) Reply() (*StartReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return startReply(buf), nil +} + +// startReply reads a byte slice into a StartReply value. +func startReply(buf []byte) *StartReply { + v := new(StartReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for Start +// startRequest writes a Start request to a byte slice. +func startRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XEVIE"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} diff --git a/vend/xgb/xf86dri/xf86dri.go b/vend/xgb/xf86dri/xf86dri.go new file mode 100644 index 0000000..c8fec53 --- /dev/null +++ b/vend/xgb/xf86dri/xf86dri.go @@ -0,0 +1,1301 @@ +// Package xf86dri is the X client API for the XFree86-DRI extension. +package xf86dri + +// This file is automatically generated from xf86dri.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XFree86-DRI extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 11, "XFree86-DRI").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XFree86-DRI could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XFree86-DRI"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XFree86-DRI"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XFree86-DRI"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XFree86-DRI"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XFree86-DRI"] = make(map[int]xgb.NewErrorFun) +} + +type DrmClipRect struct { + X1 int16 + Y1 int16 + X2 int16 + X3 int16 +} + +// DrmClipRectRead reads a byte slice into a DrmClipRect value. +func DrmClipRectRead(buf []byte, v *DrmClipRect) int { + b := 0 + + v.X1 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y1 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.X2 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.X3 = int16(xgb.Get16(buf[b:])) + b += 2 + + return b +} + +// DrmClipRectReadList reads a byte slice into a list of DrmClipRect values. +func DrmClipRectReadList(buf []byte, dest []DrmClipRect) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = DrmClipRect{} + b += DrmClipRectRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a DrmClipRect value to a byte slice. +func (v DrmClipRect) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], uint16(v.X1)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y1)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.X2)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.X3)) + b += 2 + + return buf[:b] +} + +// DrmClipRectListBytes writes a list of DrmClipRect values to a byte slice. +func DrmClipRectListBytes(buf []byte, list []DrmClipRect) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AuthConnectionCookie is a cookie used only for AuthConnection requests. +type AuthConnectionCookie struct { + *xgb.Cookie +} + +// AuthConnection sends a checked request. +// If an error occurs, it will be returned with the reply by calling AuthConnectionCookie.Reply() +func AuthConnection(c *xgb.Conn, Screen uint32, Magic uint32) AuthConnectionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'AuthConnection' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(authConnectionRequest(c, Screen, Magic), cookie) + return AuthConnectionCookie{cookie} +} + +// AuthConnectionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AuthConnectionUnchecked(c *xgb.Conn, Screen uint32, Magic uint32) AuthConnectionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'AuthConnection' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(authConnectionRequest(c, Screen, Magic), cookie) + return AuthConnectionCookie{cookie} +} + +// AuthConnectionReply represents the data returned from a AuthConnection request. +type AuthConnectionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Authenticated uint32 +} + +// Reply blocks and returns the reply data for a AuthConnection request. +func (cook AuthConnectionCookie) Reply() (*AuthConnectionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return authConnectionReply(buf), nil +} + +// authConnectionReply reads a byte slice into a AuthConnectionReply value. +func authConnectionReply(buf []byte) *AuthConnectionReply { + v := new(AuthConnectionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Authenticated = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for AuthConnection +// authConnectionRequest writes a AuthConnection request to a byte slice. +func authConnectionRequest(c *xgb.Conn, Screen uint32, Magic uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Magic) + b += 4 + + return buf +} + +// CloseConnectionCookie is a cookie used only for CloseConnection requests. +type CloseConnectionCookie struct { + *xgb.Cookie +} + +// CloseConnection sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CloseConnection(c *xgb.Conn, Screen uint32) CloseConnectionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'CloseConnection' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(closeConnectionRequest(c, Screen), cookie) + return CloseConnectionCookie{cookie} +} + +// CloseConnectionChecked sends a checked request. +// If an error occurs, it can be retrieved using CloseConnectionCookie.Check() +func CloseConnectionChecked(c *xgb.Conn, Screen uint32) CloseConnectionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'CloseConnection' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(closeConnectionRequest(c, Screen), cookie) + return CloseConnectionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CloseConnectionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CloseConnection +// closeConnectionRequest writes a CloseConnection request to a byte slice. +func closeConnectionRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// CreateContextCookie is a cookie used only for CreateContext requests. +type CreateContextCookie struct { + *xgb.Cookie +} + +// CreateContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateContextCookie.Reply() +func CreateContext(c *xgb.Conn, Screen uint32, Visual uint32, Context uint32) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createContextRequest(c, Screen, Visual, Context), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateContextUnchecked(c *xgb.Conn, Screen uint32, Visual uint32, Context uint32) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createContextRequest(c, Screen, Visual, Context), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextReply represents the data returned from a CreateContext request. +type CreateContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + HwContext uint32 +} + +// Reply blocks and returns the reply data for a CreateContext request. +func (cook CreateContextCookie) Reply() (*CreateContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createContextReply(buf), nil +} + +// createContextReply reads a byte slice into a CreateContextReply value. +func createContextReply(buf []byte) *CreateContextReply { + v := new(CreateContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.HwContext = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for CreateContext +// createContextRequest writes a CreateContext request to a byte slice. +func createContextRequest(c *xgb.Conn, Screen uint32, Visual uint32, Context uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Visual) + b += 4 + + xgb.Put32(buf[b:], Context) + b += 4 + + return buf +} + +// CreateDrawableCookie is a cookie used only for CreateDrawable requests. +type CreateDrawableCookie struct { + *xgb.Cookie +} + +// CreateDrawable sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateDrawableCookie.Reply() +func CreateDrawable(c *xgb.Conn, Screen uint32, Drawable uint32) CreateDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'CreateDrawable' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createDrawableRequest(c, Screen, Drawable), cookie) + return CreateDrawableCookie{cookie} +} + +// CreateDrawableUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateDrawableUnchecked(c *xgb.Conn, Screen uint32, Drawable uint32) CreateDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'CreateDrawable' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createDrawableRequest(c, Screen, Drawable), cookie) + return CreateDrawableCookie{cookie} +} + +// CreateDrawableReply represents the data returned from a CreateDrawable request. +type CreateDrawableReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + HwDrawableHandle uint32 +} + +// Reply blocks and returns the reply data for a CreateDrawable request. +func (cook CreateDrawableCookie) Reply() (*CreateDrawableReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createDrawableReply(buf), nil +} + +// createDrawableReply reads a byte slice into a CreateDrawableReply value. +func createDrawableReply(buf []byte) *CreateDrawableReply { + v := new(CreateDrawableReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.HwDrawableHandle = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for CreateDrawable +// createDrawableRequest writes a CreateDrawable request to a byte slice. +func createDrawableRequest(c *xgb.Conn, Screen uint32, Drawable uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Drawable) + b += 4 + + return buf +} + +// DestroyContextCookie is a cookie used only for DestroyContext requests. +type DestroyContextCookie struct { + *xgb.Cookie +} + +// DestroyContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyContext(c *xgb.Conn, Screen uint32, Context uint32) DestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'DestroyContext' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyContextRequest(c, Screen, Context), cookie) + return DestroyContextCookie{cookie} +} + +// DestroyContextChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyContextCookie.Check() +func DestroyContextChecked(c *xgb.Conn, Screen uint32, Context uint32) DestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'DestroyContext' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyContextRequest(c, Screen, Context), cookie) + return DestroyContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyContext +// destroyContextRequest writes a DestroyContext request to a byte slice. +func destroyContextRequest(c *xgb.Conn, Screen uint32, Context uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Context) + b += 4 + + return buf +} + +// DestroyDrawableCookie is a cookie used only for DestroyDrawable requests. +type DestroyDrawableCookie struct { + *xgb.Cookie +} + +// DestroyDrawable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyDrawable(c *xgb.Conn, Screen uint32, Drawable uint32) DestroyDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'DestroyDrawable' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyDrawableRequest(c, Screen, Drawable), cookie) + return DestroyDrawableCookie{cookie} +} + +// DestroyDrawableChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyDrawableCookie.Check() +func DestroyDrawableChecked(c *xgb.Conn, Screen uint32, Drawable uint32) DestroyDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'DestroyDrawable' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyDrawableRequest(c, Screen, Drawable), cookie) + return DestroyDrawableCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyDrawableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyDrawable +// destroyDrawableRequest writes a DestroyDrawable request to a byte slice. +func destroyDrawableRequest(c *xgb.Conn, Screen uint32, Drawable uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Drawable) + b += 4 + + return buf +} + +// GetClientDriverNameCookie is a cookie used only for GetClientDriverName requests. +type GetClientDriverNameCookie struct { + *xgb.Cookie +} + +// GetClientDriverName sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetClientDriverNameCookie.Reply() +func GetClientDriverName(c *xgb.Conn, Screen uint32) GetClientDriverNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'GetClientDriverName' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getClientDriverNameRequest(c, Screen), cookie) + return GetClientDriverNameCookie{cookie} +} + +// GetClientDriverNameUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetClientDriverNameUnchecked(c *xgb.Conn, Screen uint32) GetClientDriverNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'GetClientDriverName' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getClientDriverNameRequest(c, Screen), cookie) + return GetClientDriverNameCookie{cookie} +} + +// GetClientDriverNameReply represents the data returned from a GetClientDriverName request. +type GetClientDriverNameReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ClientDriverMajorVersion uint32 + ClientDriverMinorVersion uint32 + ClientDriverPatchVersion uint32 + ClientDriverNameLen uint32 + // padding: 8 bytes + ClientDriverName string // size: xgb.Pad((int(ClientDriverNameLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetClientDriverName request. +func (cook GetClientDriverNameCookie) Reply() (*GetClientDriverNameReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getClientDriverNameReply(buf), nil +} + +// getClientDriverNameReply reads a byte slice into a GetClientDriverNameReply value. +func getClientDriverNameReply(buf []byte) *GetClientDriverNameReply { + v := new(GetClientDriverNameReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ClientDriverMajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.ClientDriverMinorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.ClientDriverPatchVersion = xgb.Get32(buf[b:]) + b += 4 + + v.ClientDriverNameLen = xgb.Get32(buf[b:]) + b += 4 + + b += 8 // padding + + { + byteString := make([]byte, v.ClientDriverNameLen) + copy(byteString[:v.ClientDriverNameLen], buf[b:]) + v.ClientDriverName = string(byteString) + b += int(v.ClientDriverNameLen) + } + + return v +} + +// Write request to wire for GetClientDriverName +// getClientDriverNameRequest writes a GetClientDriverName request to a byte slice. +func getClientDriverNameRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// GetDeviceInfoCookie is a cookie used only for GetDeviceInfo requests. +type GetDeviceInfoCookie struct { + *xgb.Cookie +} + +// GetDeviceInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDeviceInfoCookie.Reply() +func GetDeviceInfo(c *xgb.Conn, Screen uint32) GetDeviceInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'GetDeviceInfo' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDeviceInfoRequest(c, Screen), cookie) + return GetDeviceInfoCookie{cookie} +} + +// GetDeviceInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDeviceInfoUnchecked(c *xgb.Conn, Screen uint32) GetDeviceInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'GetDeviceInfo' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDeviceInfoRequest(c, Screen), cookie) + return GetDeviceInfoCookie{cookie} +} + +// GetDeviceInfoReply represents the data returned from a GetDeviceInfo request. +type GetDeviceInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + FramebufferHandleLow uint32 + FramebufferHandleHigh uint32 + FramebufferOriginOffset uint32 + FramebufferSize uint32 + FramebufferStride uint32 + DevicePrivateSize uint32 + DevicePrivate []uint32 // size: xgb.Pad((int(DevicePrivateSize) * 4)) +} + +// Reply blocks and returns the reply data for a GetDeviceInfo request. +func (cook GetDeviceInfoCookie) Reply() (*GetDeviceInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDeviceInfoReply(buf), nil +} + +// getDeviceInfoReply reads a byte slice into a GetDeviceInfoReply value. +func getDeviceInfoReply(buf []byte) *GetDeviceInfoReply { + v := new(GetDeviceInfoReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.FramebufferHandleLow = xgb.Get32(buf[b:]) + b += 4 + + v.FramebufferHandleHigh = xgb.Get32(buf[b:]) + b += 4 + + v.FramebufferOriginOffset = xgb.Get32(buf[b:]) + b += 4 + + v.FramebufferSize = xgb.Get32(buf[b:]) + b += 4 + + v.FramebufferStride = xgb.Get32(buf[b:]) + b += 4 + + v.DevicePrivateSize = xgb.Get32(buf[b:]) + b += 4 + + v.DevicePrivate = make([]uint32, v.DevicePrivateSize) + for i := 0; i < int(v.DevicePrivateSize); i++ { + v.DevicePrivate[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetDeviceInfo +// getDeviceInfoRequest writes a GetDeviceInfo request to a byte slice. +func getDeviceInfoRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// GetDrawableInfoCookie is a cookie used only for GetDrawableInfo requests. +type GetDrawableInfoCookie struct { + *xgb.Cookie +} + +// GetDrawableInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDrawableInfoCookie.Reply() +func GetDrawableInfo(c *xgb.Conn, Screen uint32, Drawable uint32) GetDrawableInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'GetDrawableInfo' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDrawableInfoRequest(c, Screen, Drawable), cookie) + return GetDrawableInfoCookie{cookie} +} + +// GetDrawableInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDrawableInfoUnchecked(c *xgb.Conn, Screen uint32, Drawable uint32) GetDrawableInfoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'GetDrawableInfo' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDrawableInfoRequest(c, Screen, Drawable), cookie) + return GetDrawableInfoCookie{cookie} +} + +// GetDrawableInfoReply represents the data returned from a GetDrawableInfo request. +type GetDrawableInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + DrawableTableIndex uint32 + DrawableTableStamp uint32 + DrawableOriginX int16 + DrawableOriginY int16 + DrawableSizeW int16 + DrawableSizeH int16 + NumClipRects uint32 + BackX int16 + BackY int16 + NumBackClipRects uint32 + ClipRects []DrmClipRect // size: xgb.Pad((int(NumClipRects) * 8)) + BackClipRects []DrmClipRect // size: xgb.Pad((int(NumBackClipRects) * 8)) +} + +// Reply blocks and returns the reply data for a GetDrawableInfo request. +func (cook GetDrawableInfoCookie) Reply() (*GetDrawableInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDrawableInfoReply(buf), nil +} + +// getDrawableInfoReply reads a byte slice into a GetDrawableInfoReply value. +func getDrawableInfoReply(buf []byte) *GetDrawableInfoReply { + v := new(GetDrawableInfoReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.DrawableTableIndex = xgb.Get32(buf[b:]) + b += 4 + + v.DrawableTableStamp = xgb.Get32(buf[b:]) + b += 4 + + v.DrawableOriginX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.DrawableOriginY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.DrawableSizeW = int16(xgb.Get16(buf[b:])) + b += 2 + + v.DrawableSizeH = int16(xgb.Get16(buf[b:])) + b += 2 + + v.NumClipRects = xgb.Get32(buf[b:]) + b += 4 + + v.BackX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.BackY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.NumBackClipRects = xgb.Get32(buf[b:]) + b += 4 + + v.ClipRects = make([]DrmClipRect, v.NumClipRects) + b += DrmClipRectReadList(buf[b:], v.ClipRects) + + v.BackClipRects = make([]DrmClipRect, v.NumBackClipRects) + b += DrmClipRectReadList(buf[b:], v.BackClipRects) + + return v +} + +// Write request to wire for GetDrawableInfo +// getDrawableInfoRequest writes a GetDrawableInfo request to a byte slice. +func getDrawableInfoRequest(c *xgb.Conn, Screen uint32, Drawable uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], Drawable) + b += 4 + + return buf +} + +// OpenConnectionCookie is a cookie used only for OpenConnection requests. +type OpenConnectionCookie struct { + *xgb.Cookie +} + +// OpenConnection sends a checked request. +// If an error occurs, it will be returned with the reply by calling OpenConnectionCookie.Reply() +func OpenConnection(c *xgb.Conn, Screen uint32) OpenConnectionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'OpenConnection' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(openConnectionRequest(c, Screen), cookie) + return OpenConnectionCookie{cookie} +} + +// OpenConnectionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func OpenConnectionUnchecked(c *xgb.Conn, Screen uint32) OpenConnectionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'OpenConnection' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(openConnectionRequest(c, Screen), cookie) + return OpenConnectionCookie{cookie} +} + +// OpenConnectionReply represents the data returned from a OpenConnection request. +type OpenConnectionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + SareaHandleLow uint32 + SareaHandleHigh uint32 + BusIdLen uint32 + // padding: 12 bytes + BusId string // size: xgb.Pad((int(BusIdLen) * 1)) +} + +// Reply blocks and returns the reply data for a OpenConnection request. +func (cook OpenConnectionCookie) Reply() (*OpenConnectionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return openConnectionReply(buf), nil +} + +// openConnectionReply reads a byte slice into a OpenConnectionReply value. +func openConnectionReply(buf []byte) *OpenConnectionReply { + v := new(OpenConnectionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.SareaHandleLow = xgb.Get32(buf[b:]) + b += 4 + + v.SareaHandleHigh = xgb.Get32(buf[b:]) + b += 4 + + v.BusIdLen = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + { + byteString := make([]byte, v.BusIdLen) + copy(byteString[:v.BusIdLen], buf[b:]) + v.BusId = string(byteString) + b += int(v.BusIdLen) + } + + return v +} + +// Write request to wire for OpenConnection +// openConnectionRequest writes a OpenConnection request to a byte slice. +func openConnectionRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// QueryDirectRenderingCapableCookie is a cookie used only for QueryDirectRenderingCapable requests. +type QueryDirectRenderingCapableCookie struct { + *xgb.Cookie +} + +// QueryDirectRenderingCapable sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryDirectRenderingCapableCookie.Reply() +func QueryDirectRenderingCapable(c *xgb.Conn, Screen uint32) QueryDirectRenderingCapableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'QueryDirectRenderingCapable' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryDirectRenderingCapableRequest(c, Screen), cookie) + return QueryDirectRenderingCapableCookie{cookie} +} + +// QueryDirectRenderingCapableUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryDirectRenderingCapableUnchecked(c *xgb.Conn, Screen uint32) QueryDirectRenderingCapableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'QueryDirectRenderingCapable' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryDirectRenderingCapableRequest(c, Screen), cookie) + return QueryDirectRenderingCapableCookie{cookie} +} + +// QueryDirectRenderingCapableReply represents the data returned from a QueryDirectRenderingCapable request. +type QueryDirectRenderingCapableReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + IsCapable bool +} + +// Reply blocks and returns the reply data for a QueryDirectRenderingCapable request. +func (cook QueryDirectRenderingCapableCookie) Reply() (*QueryDirectRenderingCapableReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryDirectRenderingCapableReply(buf), nil +} + +// queryDirectRenderingCapableReply reads a byte slice into a QueryDirectRenderingCapableReply value. +func queryDirectRenderingCapableReply(buf []byte) *QueryDirectRenderingCapableReply { + v := new(QueryDirectRenderingCapableReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.IsCapable = true + } else { + v.IsCapable = false + } + b += 1 + + return v +} + +// Write request to wire for QueryDirectRenderingCapable +// queryDirectRenderingCapableRequest writes a QueryDirectRenderingCapable request to a byte slice. +func queryDirectRenderingCapableRequest(c *xgb.Conn, Screen uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-DRI"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XFree86-DRI'. xf86dri.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + DriMajorVersion uint16 + DriMinorVersion uint16 + DriMinorPatch uint32 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.DriMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.DriMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.DriMinorPatch = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-DRI"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} diff --git a/vend/xgb/xf86vidmode/xf86vidmode.go b/vend/xgb/xf86vidmode/xf86vidmode.go new file mode 100644 index 0000000..8b605e2 --- /dev/null +++ b/vend/xgb/xf86vidmode/xf86vidmode.go @@ -0,0 +1,2688 @@ +// Package xf86vidmode is the X client API for the XFree86-VidModeExtension extension. +package xf86vidmode + +// This file is automatically generated from xf86vidmode.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XFree86-VidModeExtension extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 24, "XFree86-VidModeExtension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XFree86-VidModeExtension could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XFree86-VidModeExtension"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XFree86-VidModeExtension"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XFree86-VidModeExtension"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XFree86-VidModeExtension"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadClock is the error number for a BadBadClock. +const BadBadClock = 0 + +type BadClockError struct { + Sequence uint16 + NiceName string +} + +// BadClockErrorNew constructs a BadClockError value that implements xgb.Error from a byte slice. +func BadClockErrorNew(buf []byte) xgb.Error { + v := BadClockError{} + v.NiceName = "BadClock" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadClock error. +// This is mostly used internally. +func (err BadClockError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadClock error. If no bad value exists, 0 is returned. +func (err BadClockError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadClock error. + +func (err BadClockError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadClock {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][0] = BadClockErrorNew +} + +// BadBadHTimings is the error number for a BadBadHTimings. +const BadBadHTimings = 1 + +type BadHTimingsError struct { + Sequence uint16 + NiceName string +} + +// BadHTimingsErrorNew constructs a BadHTimingsError value that implements xgb.Error from a byte slice. +func BadHTimingsErrorNew(buf []byte) xgb.Error { + v := BadHTimingsError{} + v.NiceName = "BadHTimings" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadHTimings error. +// This is mostly used internally. +func (err BadHTimingsError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadHTimings error. If no bad value exists, 0 is returned. +func (err BadHTimingsError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadHTimings error. + +func (err BadHTimingsError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadHTimings {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][1] = BadHTimingsErrorNew +} + +// BadBadVTimings is the error number for a BadBadVTimings. +const BadBadVTimings = 2 + +type BadVTimingsError struct { + Sequence uint16 + NiceName string +} + +// BadVTimingsErrorNew constructs a BadVTimingsError value that implements xgb.Error from a byte slice. +func BadVTimingsErrorNew(buf []byte) xgb.Error { + v := BadVTimingsError{} + v.NiceName = "BadVTimings" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadVTimings error. +// This is mostly used internally. +func (err BadVTimingsError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadVTimings error. If no bad value exists, 0 is returned. +func (err BadVTimingsError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadVTimings error. + +func (err BadVTimingsError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadVTimings {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][2] = BadVTimingsErrorNew +} + +// BadClientNotLocal is the error number for a BadClientNotLocal. +const BadClientNotLocal = 5 + +type ClientNotLocalError struct { + Sequence uint16 + NiceName string +} + +// ClientNotLocalErrorNew constructs a ClientNotLocalError value that implements xgb.Error from a byte slice. +func ClientNotLocalErrorNew(buf []byte) xgb.Error { + v := ClientNotLocalError{} + v.NiceName = "ClientNotLocal" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadClientNotLocal error. +// This is mostly used internally. +func (err ClientNotLocalError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadClientNotLocal error. If no bad value exists, 0 is returned. +func (err ClientNotLocalError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadClientNotLocal error. + +func (err ClientNotLocalError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadClientNotLocal {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][5] = ClientNotLocalErrorNew +} + +const ( + ClockFlagProgramable = 1 +) + +type Dotclock uint32 + +// BadExtensionDisabled is the error number for a BadExtensionDisabled. +const BadExtensionDisabled = 4 + +type ExtensionDisabledError struct { + Sequence uint16 + NiceName string +} + +// ExtensionDisabledErrorNew constructs a ExtensionDisabledError value that implements xgb.Error from a byte slice. +func ExtensionDisabledErrorNew(buf []byte) xgb.Error { + v := ExtensionDisabledError{} + v.NiceName = "ExtensionDisabled" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadExtensionDisabled error. +// This is mostly used internally. +func (err ExtensionDisabledError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadExtensionDisabled error. If no bad value exists, 0 is returned. +func (err ExtensionDisabledError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadExtensionDisabled error. + +func (err ExtensionDisabledError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadExtensionDisabled {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][4] = ExtensionDisabledErrorNew +} + +const ( + ModeFlagPositiveHsync = 1 + ModeFlagNegativeHsync = 2 + ModeFlagPositiveVsync = 4 + ModeFlagNegativeVsync = 8 + ModeFlagInterlace = 16 + ModeFlagCompositeSync = 32 + ModeFlagPositiveCsync = 64 + ModeFlagNegativeCsync = 128 + ModeFlagHSkew = 256 + ModeFlagBroadcast = 512 + ModeFlagPixmux = 1024 + ModeFlagDoubleClock = 2048 + ModeFlagHalfClock = 4096 +) + +type ModeInfo struct { + Dotclock Dotclock + Hdisplay uint16 + Hsyncstart uint16 + Hsyncend uint16 + Htotal uint16 + Hskew uint32 + Vdisplay uint16 + Vsyncstart uint16 + Vsyncend uint16 + Vtotal uint16 + // padding: 4 bytes + Flags uint32 + // padding: 12 bytes + Privsize uint32 +} + +// ModeInfoRead reads a byte slice into a ModeInfo value. +func ModeInfoRead(buf []byte, v *ModeInfo) int { + b := 0 + + v.Dotclock = Dotclock(xgb.Get32(buf[b:])) + b += 4 + + v.Hdisplay = xgb.Get16(buf[b:]) + b += 2 + + v.Hsyncstart = xgb.Get16(buf[b:]) + b += 2 + + v.Hsyncend = xgb.Get16(buf[b:]) + b += 2 + + v.Htotal = xgb.Get16(buf[b:]) + b += 2 + + v.Hskew = xgb.Get32(buf[b:]) + b += 4 + + v.Vdisplay = xgb.Get16(buf[b:]) + b += 2 + + v.Vsyncstart = xgb.Get16(buf[b:]) + b += 2 + + v.Vsyncend = xgb.Get16(buf[b:]) + b += 2 + + v.Vtotal = xgb.Get16(buf[b:]) + b += 2 + + b += 4 // padding + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Privsize = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// ModeInfoReadList reads a byte slice into a list of ModeInfo values. +func ModeInfoReadList(buf []byte, dest []ModeInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ModeInfo{} + b += ModeInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ModeInfo value to a byte slice. +func (v ModeInfo) Bytes() []byte { + buf := make([]byte, 48) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Dotclock)) + b += 4 + + xgb.Put16(buf[b:], v.Hdisplay) + b += 2 + + xgb.Put16(buf[b:], v.Hsyncstart) + b += 2 + + xgb.Put16(buf[b:], v.Hsyncend) + b += 2 + + xgb.Put16(buf[b:], v.Htotal) + b += 2 + + xgb.Put32(buf[b:], v.Hskew) + b += 4 + + xgb.Put16(buf[b:], v.Vdisplay) + b += 2 + + xgb.Put16(buf[b:], v.Vsyncstart) + b += 2 + + xgb.Put16(buf[b:], v.Vsyncend) + b += 2 + + xgb.Put16(buf[b:], v.Vtotal) + b += 2 + + b += 4 // padding + + xgb.Put32(buf[b:], v.Flags) + b += 4 + + b += 12 // padding + + xgb.Put32(buf[b:], v.Privsize) + b += 4 + + return buf[:b] +} + +// ModeInfoListBytes writes a list of ModeInfo values to a byte slice. +func ModeInfoListBytes(buf []byte, list []ModeInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// BadModeUnsuitable is the error number for a BadModeUnsuitable. +const BadModeUnsuitable = 3 + +type ModeUnsuitableError struct { + Sequence uint16 + NiceName string +} + +// ModeUnsuitableErrorNew constructs a ModeUnsuitableError value that implements xgb.Error from a byte slice. +func ModeUnsuitableErrorNew(buf []byte) xgb.Error { + v := ModeUnsuitableError{} + v.NiceName = "ModeUnsuitable" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadModeUnsuitable error. +// This is mostly used internally. +func (err ModeUnsuitableError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadModeUnsuitable error. If no bad value exists, 0 is returned. +func (err ModeUnsuitableError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadModeUnsuitable error. + +func (err ModeUnsuitableError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadModeUnsuitable {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][3] = ModeUnsuitableErrorNew +} + +const ( + PermissionRead = 1 + PermissionWrite = 2 +) + +type Syncrange uint32 + +// BadZoomLocked is the error number for a BadZoomLocked. +const BadZoomLocked = 6 + +type ZoomLockedError struct { + Sequence uint16 + NiceName string +} + +// ZoomLockedErrorNew constructs a ZoomLockedError value that implements xgb.Error from a byte slice. +func ZoomLockedErrorNew(buf []byte) xgb.Error { + v := ZoomLockedError{} + v.NiceName = "ZoomLocked" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadZoomLocked error. +// This is mostly used internally. +func (err ZoomLockedError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadZoomLocked error. If no bad value exists, 0 is returned. +func (err ZoomLockedError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadZoomLocked error. + +func (err ZoomLockedError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadZoomLocked {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFree86-VidModeExtension"][6] = ZoomLockedErrorNew +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AddModeLineCookie is a cookie used only for AddModeLine requests. +type AddModeLineCookie struct { + *xgb.Cookie +} + +// AddModeLine sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AddModeLine(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, AfterDotclock Dotclock, AfterHdisplay uint16, AfterHsyncstart uint16, AfterHsyncend uint16, AfterHtotal uint16, AfterHskew uint16, AfterVdisplay uint16, AfterVsyncstart uint16, AfterVsyncend uint16, AfterVtotal uint16, AfterFlags uint32, Private []byte) AddModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'AddModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(addModeLineRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, AfterDotclock, AfterHdisplay, AfterHsyncstart, AfterHsyncend, AfterHtotal, AfterHskew, AfterVdisplay, AfterVsyncstart, AfterVsyncend, AfterVtotal, AfterFlags, Private), cookie) + return AddModeLineCookie{cookie} +} + +// AddModeLineChecked sends a checked request. +// If an error occurs, it can be retrieved using AddModeLineCookie.Check() +func AddModeLineChecked(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, AfterDotclock Dotclock, AfterHdisplay uint16, AfterHsyncstart uint16, AfterHsyncend uint16, AfterHtotal uint16, AfterHskew uint16, AfterVdisplay uint16, AfterVsyncstart uint16, AfterVsyncend uint16, AfterVtotal uint16, AfterFlags uint32, Private []byte) AddModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'AddModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(addModeLineRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, AfterDotclock, AfterHdisplay, AfterHsyncstart, AfterHsyncend, AfterHtotal, AfterHskew, AfterVdisplay, AfterVsyncstart, AfterVsyncend, AfterVtotal, AfterFlags, Private), cookie) + return AddModeLineCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AddModeLineCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for AddModeLine +// addModeLineRequest writes a AddModeLine request to a byte slice. +func addModeLineRequest(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, AfterDotclock Dotclock, AfterHdisplay uint16, AfterHsyncstart uint16, AfterHsyncend uint16, AfterHtotal uint16, AfterHskew uint16, AfterVdisplay uint16, AfterVsyncstart uint16, AfterVsyncend uint16, AfterVtotal uint16, AfterFlags uint32, Private []byte) []byte { + size := xgb.Pad((92 + xgb.Pad((int(Privsize) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Dotclock)) + b += 4 + + xgb.Put16(buf[b:], Hdisplay) + b += 2 + + xgb.Put16(buf[b:], Hsyncstart) + b += 2 + + xgb.Put16(buf[b:], Hsyncend) + b += 2 + + xgb.Put16(buf[b:], Htotal) + b += 2 + + xgb.Put16(buf[b:], Hskew) + b += 2 + + xgb.Put16(buf[b:], Vdisplay) + b += 2 + + xgb.Put16(buf[b:], Vsyncstart) + b += 2 + + xgb.Put16(buf[b:], Vsyncend) + b += 2 + + xgb.Put16(buf[b:], Vtotal) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], Flags) + b += 4 + + b += 12 // padding + + xgb.Put32(buf[b:], Privsize) + b += 4 + + xgb.Put32(buf[b:], uint32(AfterDotclock)) + b += 4 + + xgb.Put16(buf[b:], AfterHdisplay) + b += 2 + + xgb.Put16(buf[b:], AfterHsyncstart) + b += 2 + + xgb.Put16(buf[b:], AfterHsyncend) + b += 2 + + xgb.Put16(buf[b:], AfterHtotal) + b += 2 + + xgb.Put16(buf[b:], AfterHskew) + b += 2 + + xgb.Put16(buf[b:], AfterVdisplay) + b += 2 + + xgb.Put16(buf[b:], AfterVsyncstart) + b += 2 + + xgb.Put16(buf[b:], AfterVsyncend) + b += 2 + + xgb.Put16(buf[b:], AfterVtotal) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], AfterFlags) + b += 4 + + b += 12 // padding + + copy(buf[b:], Private[:Privsize]) + b += int(Privsize) + + return buf +} + +// DeleteModeLineCookie is a cookie used only for DeleteModeLine requests. +type DeleteModeLineCookie struct { + *xgb.Cookie +} + +// DeleteModeLine sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteModeLine(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) DeleteModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'DeleteModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteModeLineRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return DeleteModeLineCookie{cookie} +} + +// DeleteModeLineChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteModeLineCookie.Check() +func DeleteModeLineChecked(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) DeleteModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'DeleteModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteModeLineRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return DeleteModeLineCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteModeLineCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteModeLine +// deleteModeLineRequest writes a DeleteModeLine request to a byte slice. +func deleteModeLineRequest(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) []byte { + size := xgb.Pad((52 + xgb.Pad((int(Privsize) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Dotclock)) + b += 4 + + xgb.Put16(buf[b:], Hdisplay) + b += 2 + + xgb.Put16(buf[b:], Hsyncstart) + b += 2 + + xgb.Put16(buf[b:], Hsyncend) + b += 2 + + xgb.Put16(buf[b:], Htotal) + b += 2 + + xgb.Put16(buf[b:], Hskew) + b += 2 + + xgb.Put16(buf[b:], Vdisplay) + b += 2 + + xgb.Put16(buf[b:], Vsyncstart) + b += 2 + + xgb.Put16(buf[b:], Vsyncend) + b += 2 + + xgb.Put16(buf[b:], Vtotal) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], Flags) + b += 4 + + b += 12 // padding + + xgb.Put32(buf[b:], Privsize) + b += 4 + + copy(buf[b:], Private[:Privsize]) + b += int(Privsize) + + return buf +} + +// GetAllModeLinesCookie is a cookie used only for GetAllModeLines requests. +type GetAllModeLinesCookie struct { + *xgb.Cookie +} + +// GetAllModeLines sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetAllModeLinesCookie.Reply() +func GetAllModeLines(c *xgb.Conn, Screen uint16) GetAllModeLinesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetAllModeLines' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getAllModeLinesRequest(c, Screen), cookie) + return GetAllModeLinesCookie{cookie} +} + +// GetAllModeLinesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetAllModeLinesUnchecked(c *xgb.Conn, Screen uint16) GetAllModeLinesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetAllModeLines' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getAllModeLinesRequest(c, Screen), cookie) + return GetAllModeLinesCookie{cookie} +} + +// GetAllModeLinesReply represents the data returned from a GetAllModeLines request. +type GetAllModeLinesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Modecount uint32 + // padding: 20 bytes + Modeinfo []ModeInfo // size: xgb.Pad((int(Modecount) * 48)) +} + +// Reply blocks and returns the reply data for a GetAllModeLines request. +func (cook GetAllModeLinesCookie) Reply() (*GetAllModeLinesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getAllModeLinesReply(buf), nil +} + +// getAllModeLinesReply reads a byte slice into a GetAllModeLinesReply value. +func getAllModeLinesReply(buf []byte) *GetAllModeLinesReply { + v := new(GetAllModeLinesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Modecount = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Modeinfo = make([]ModeInfo, v.Modecount) + b += ModeInfoReadList(buf[b:], v.Modeinfo) + + return v +} + +// Write request to wire for GetAllModeLines +// getAllModeLinesRequest writes a GetAllModeLines request to a byte slice. +func getAllModeLinesRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// GetDotClocksCookie is a cookie used only for GetDotClocks requests. +type GetDotClocksCookie struct { + *xgb.Cookie +} + +// GetDotClocks sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDotClocksCookie.Reply() +func GetDotClocks(c *xgb.Conn, Screen uint16) GetDotClocksCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetDotClocks' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDotClocksRequest(c, Screen), cookie) + return GetDotClocksCookie{cookie} +} + +// GetDotClocksUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDotClocksUnchecked(c *xgb.Conn, Screen uint16) GetDotClocksCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetDotClocks' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDotClocksRequest(c, Screen), cookie) + return GetDotClocksCookie{cookie} +} + +// GetDotClocksReply represents the data returned from a GetDotClocks request. +type GetDotClocksReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Flags uint32 + Clocks uint32 + Maxclocks uint32 + // padding: 12 bytes + Clock []uint32 // size: xgb.Pad((((1 - (int(Flags) & 1)) * int(Clocks)) * 4)) +} + +// Reply blocks and returns the reply data for a GetDotClocks request. +func (cook GetDotClocksCookie) Reply() (*GetDotClocksReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDotClocksReply(buf), nil +} + +// getDotClocksReply reads a byte slice into a GetDotClocksReply value. +func getDotClocksReply(buf []byte) *GetDotClocksReply { + v := new(GetDotClocksReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + v.Clocks = xgb.Get32(buf[b:]) + b += 4 + + v.Maxclocks = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Clock = make([]uint32, ((1 - (int(v.Flags) & 1)) * int(v.Clocks))) + for i := 0; i < int(((1 - (int(v.Flags) & 1)) * int(v.Clocks))); i++ { + v.Clock[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetDotClocks +// getDotClocksRequest writes a GetDotClocks request to a byte slice. +func getDotClocksRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// GetGammaCookie is a cookie used only for GetGamma requests. +type GetGammaCookie struct { + *xgb.Cookie +} + +// GetGamma sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetGammaCookie.Reply() +func GetGamma(c *xgb.Conn, Screen uint16) GetGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetGamma' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getGammaRequest(c, Screen), cookie) + return GetGammaCookie{cookie} +} + +// GetGammaUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetGammaUnchecked(c *xgb.Conn, Screen uint16) GetGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetGamma' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getGammaRequest(c, Screen), cookie) + return GetGammaCookie{cookie} +} + +// GetGammaReply represents the data returned from a GetGamma request. +type GetGammaReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Red uint32 + Green uint32 + Blue uint32 + // padding: 12 bytes +} + +// Reply blocks and returns the reply data for a GetGamma request. +func (cook GetGammaCookie) Reply() (*GetGammaReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getGammaReply(buf), nil +} + +// getGammaReply reads a byte slice into a GetGammaReply value. +func getGammaReply(buf []byte) *GetGammaReply { + v := new(GetGammaReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Red = xgb.Get32(buf[b:]) + b += 4 + + v.Green = xgb.Get32(buf[b:]) + b += 4 + + v.Blue = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + return v +} + +// Write request to wire for GetGamma +// getGammaRequest writes a GetGamma request to a byte slice. +func getGammaRequest(c *xgb.Conn, Screen uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 26 // padding + + return buf +} + +// GetGammaRampCookie is a cookie used only for GetGammaRamp requests. +type GetGammaRampCookie struct { + *xgb.Cookie +} + +// GetGammaRamp sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetGammaRampCookie.Reply() +func GetGammaRamp(c *xgb.Conn, Screen uint16, Size uint16) GetGammaRampCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetGammaRamp' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getGammaRampRequest(c, Screen, Size), cookie) + return GetGammaRampCookie{cookie} +} + +// GetGammaRampUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetGammaRampUnchecked(c *xgb.Conn, Screen uint16, Size uint16) GetGammaRampCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetGammaRamp' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getGammaRampRequest(c, Screen, Size), cookie) + return GetGammaRampCookie{cookie} +} + +// GetGammaRampReply represents the data returned from a GetGammaRamp request. +type GetGammaRampReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Size uint16 + // padding: 22 bytes + Red []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) + Green []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) + Blue []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) +} + +// Reply blocks and returns the reply data for a GetGammaRamp request. +func (cook GetGammaRampCookie) Reply() (*GetGammaRampReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getGammaRampReply(buf), nil +} + +// getGammaRampReply reads a byte slice into a GetGammaRampReply value. +func getGammaRampReply(buf []byte) *GetGammaRampReply { + v := new(GetGammaRampReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Size = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Red = make([]uint16, ((int(v.Size) + 1) & -2)) + for i := 0; i < int(((int(v.Size) + 1) & -2)); i++ { + v.Red[i] = xgb.Get16(buf[b:]) + b += 2 + } + + v.Green = make([]uint16, ((int(v.Size) + 1) & -2)) + for i := 0; i < int(((int(v.Size) + 1) & -2)); i++ { + v.Green[i] = xgb.Get16(buf[b:]) + b += 2 + } + + v.Blue = make([]uint16, ((int(v.Size) + 1) & -2)) + for i := 0; i < int(((int(v.Size) + 1) & -2)); i++ { + v.Blue[i] = xgb.Get16(buf[b:]) + b += 2 + } + + return v +} + +// Write request to wire for GetGammaRamp +// getGammaRampRequest writes a GetGammaRamp request to a byte slice. +func getGammaRampRequest(c *xgb.Conn, Screen uint16, Size uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + xgb.Put16(buf[b:], Size) + b += 2 + + return buf +} + +// GetGammaRampSizeCookie is a cookie used only for GetGammaRampSize requests. +type GetGammaRampSizeCookie struct { + *xgb.Cookie +} + +// GetGammaRampSize sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetGammaRampSizeCookie.Reply() +func GetGammaRampSize(c *xgb.Conn, Screen uint16) GetGammaRampSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetGammaRampSize' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getGammaRampSizeRequest(c, Screen), cookie) + return GetGammaRampSizeCookie{cookie} +} + +// GetGammaRampSizeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetGammaRampSizeUnchecked(c *xgb.Conn, Screen uint16) GetGammaRampSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetGammaRampSize' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getGammaRampSizeRequest(c, Screen), cookie) + return GetGammaRampSizeCookie{cookie} +} + +// GetGammaRampSizeReply represents the data returned from a GetGammaRampSize request. +type GetGammaRampSizeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Size uint16 + // padding: 22 bytes +} + +// Reply blocks and returns the reply data for a GetGammaRampSize request. +func (cook GetGammaRampSizeCookie) Reply() (*GetGammaRampSizeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getGammaRampSizeReply(buf), nil +} + +// getGammaRampSizeReply reads a byte slice into a GetGammaRampSizeReply value. +func getGammaRampSizeReply(buf []byte) *GetGammaRampSizeReply { + v := new(GetGammaRampSizeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Size = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + return v +} + +// Write request to wire for GetGammaRampSize +// getGammaRampSizeRequest writes a GetGammaRampSize request to a byte slice. +func getGammaRampSizeRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// GetModeLineCookie is a cookie used only for GetModeLine requests. +type GetModeLineCookie struct { + *xgb.Cookie +} + +// GetModeLine sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetModeLineCookie.Reply() +func GetModeLine(c *xgb.Conn, Screen uint16) GetModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getModeLineRequest(c, Screen), cookie) + return GetModeLineCookie{cookie} +} + +// GetModeLineUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetModeLineUnchecked(c *xgb.Conn, Screen uint16) GetModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getModeLineRequest(c, Screen), cookie) + return GetModeLineCookie{cookie} +} + +// GetModeLineReply represents the data returned from a GetModeLine request. +type GetModeLineReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Dotclock Dotclock + Hdisplay uint16 + Hsyncstart uint16 + Hsyncend uint16 + Htotal uint16 + Hskew uint16 + Vdisplay uint16 + Vsyncstart uint16 + Vsyncend uint16 + Vtotal uint16 + // padding: 2 bytes + Flags uint32 + // padding: 12 bytes + Privsize uint32 + Private []byte // size: xgb.Pad((int(Privsize) * 1)) +} + +// Reply blocks and returns the reply data for a GetModeLine request. +func (cook GetModeLineCookie) Reply() (*GetModeLineReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getModeLineReply(buf), nil +} + +// getModeLineReply reads a byte slice into a GetModeLineReply value. +func getModeLineReply(buf []byte) *GetModeLineReply { + v := new(GetModeLineReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Dotclock = Dotclock(xgb.Get32(buf[b:])) + b += 4 + + v.Hdisplay = xgb.Get16(buf[b:]) + b += 2 + + v.Hsyncstart = xgb.Get16(buf[b:]) + b += 2 + + v.Hsyncend = xgb.Get16(buf[b:]) + b += 2 + + v.Htotal = xgb.Get16(buf[b:]) + b += 2 + + v.Hskew = xgb.Get16(buf[b:]) + b += 2 + + v.Vdisplay = xgb.Get16(buf[b:]) + b += 2 + + v.Vsyncstart = xgb.Get16(buf[b:]) + b += 2 + + v.Vsyncend = xgb.Get16(buf[b:]) + b += 2 + + v.Vtotal = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Privsize = xgb.Get32(buf[b:]) + b += 4 + + v.Private = make([]byte, v.Privsize) + copy(v.Private[:v.Privsize], buf[b:]) + b += int(v.Privsize) + + return v +} + +// Write request to wire for GetModeLine +// getModeLineRequest writes a GetModeLine request to a byte slice. +func getModeLineRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// GetMonitorCookie is a cookie used only for GetMonitor requests. +type GetMonitorCookie struct { + *xgb.Cookie +} + +// GetMonitor sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMonitorCookie.Reply() +func GetMonitor(c *xgb.Conn, Screen uint16) GetMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetMonitor' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMonitorRequest(c, Screen), cookie) + return GetMonitorCookie{cookie} +} + +// GetMonitorUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMonitorUnchecked(c *xgb.Conn, Screen uint16) GetMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetMonitor' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMonitorRequest(c, Screen), cookie) + return GetMonitorCookie{cookie} +} + +// GetMonitorReply represents the data returned from a GetMonitor request. +type GetMonitorReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + VendorLength byte + ModelLength byte + NumHsync byte + NumVsync byte + // padding: 20 bytes + Hsync []Syncrange // size: xgb.Pad((int(NumHsync) * 4)) + Vsync []Syncrange // size: xgb.Pad((int(NumVsync) * 4)) + Vendor string // size: xgb.Pad((int(VendorLength) * 1)) + AlignmentPad []byte // size: xgb.Pad(((((int(VendorLength) + 3) & -4) - int(VendorLength)) * 1)) + Model string // size: xgb.Pad((int(ModelLength) * 1)) +} + +// Reply blocks and returns the reply data for a GetMonitor request. +func (cook GetMonitorCookie) Reply() (*GetMonitorReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMonitorReply(buf), nil +} + +// getMonitorReply reads a byte slice into a GetMonitorReply value. +func getMonitorReply(buf []byte) *GetMonitorReply { + v := new(GetMonitorReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.VendorLength = buf[b] + b += 1 + + v.ModelLength = buf[b] + b += 1 + + v.NumHsync = buf[b] + b += 1 + + v.NumVsync = buf[b] + b += 1 + + b += 20 // padding + + v.Hsync = make([]Syncrange, v.NumHsync) + for i := 0; i < int(v.NumHsync); i++ { + v.Hsync[i] = Syncrange(xgb.Get32(buf[b:])) + b += 4 + } + + v.Vsync = make([]Syncrange, v.NumVsync) + for i := 0; i < int(v.NumVsync); i++ { + v.Vsync[i] = Syncrange(xgb.Get32(buf[b:])) + b += 4 + } + + { + byteString := make([]byte, v.VendorLength) + copy(byteString[:v.VendorLength], buf[b:]) + v.Vendor = string(byteString) + b += int(v.VendorLength) + } + + v.AlignmentPad = make([]byte, (((int(v.VendorLength) + 3) & -4) - int(v.VendorLength))) + copy(v.AlignmentPad[:(((int(v.VendorLength)+3)&-4)-int(v.VendorLength))], buf[b:]) + b += int((((int(v.VendorLength) + 3) & -4) - int(v.VendorLength))) + + { + byteString := make([]byte, v.ModelLength) + copy(byteString[:v.ModelLength], buf[b:]) + v.Model = string(byteString) + b += int(v.ModelLength) + } + + return v +} + +// Write request to wire for GetMonitor +// getMonitorRequest writes a GetMonitor request to a byte slice. +func getMonitorRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// GetPermissionsCookie is a cookie used only for GetPermissions requests. +type GetPermissionsCookie struct { + *xgb.Cookie +} + +// GetPermissions sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPermissionsCookie.Reply() +func GetPermissions(c *xgb.Conn, Screen uint16) GetPermissionsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetPermissions' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPermissionsRequest(c, Screen), cookie) + return GetPermissionsCookie{cookie} +} + +// GetPermissionsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPermissionsUnchecked(c *xgb.Conn, Screen uint16) GetPermissionsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetPermissions' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPermissionsRequest(c, Screen), cookie) + return GetPermissionsCookie{cookie} +} + +// GetPermissionsReply represents the data returned from a GetPermissions request. +type GetPermissionsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Permissions uint32 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a GetPermissions request. +func (cook GetPermissionsCookie) Reply() (*GetPermissionsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPermissionsReply(buf), nil +} + +// getPermissionsReply reads a byte slice into a GetPermissionsReply value. +func getPermissionsReply(buf []byte) *GetPermissionsReply { + v := new(GetPermissionsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Permissions = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for GetPermissions +// getPermissionsRequest writes a GetPermissions request to a byte slice. +func getPermissionsRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// GetViewPortCookie is a cookie used only for GetViewPort requests. +type GetViewPortCookie struct { + *xgb.Cookie +} + +// GetViewPort sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetViewPortCookie.Reply() +func GetViewPort(c *xgb.Conn, Screen uint16) GetViewPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetViewPort' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getViewPortRequest(c, Screen), cookie) + return GetViewPortCookie{cookie} +} + +// GetViewPortUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetViewPortUnchecked(c *xgb.Conn, Screen uint16) GetViewPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'GetViewPort' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getViewPortRequest(c, Screen), cookie) + return GetViewPortCookie{cookie} +} + +// GetViewPortReply represents the data returned from a GetViewPort request. +type GetViewPortReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + X uint32 + Y uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a GetViewPort request. +func (cook GetViewPortCookie) Reply() (*GetViewPortReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getViewPortReply(buf), nil +} + +// getViewPortReply reads a byte slice into a GetViewPortReply value. +func getViewPortReply(buf []byte) *GetViewPortReply { + v := new(GetViewPortReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.X = xgb.Get32(buf[b:]) + b += 4 + + v.Y = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for GetViewPort +// getViewPortRequest writes a GetViewPort request to a byte slice. +func getViewPortRequest(c *xgb.Conn, Screen uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + return buf +} + +// LockModeSwitchCookie is a cookie used only for LockModeSwitch requests. +type LockModeSwitchCookie struct { + *xgb.Cookie +} + +// LockModeSwitch sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func LockModeSwitch(c *xgb.Conn, Screen uint16, Lock uint16) LockModeSwitchCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'LockModeSwitch' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(lockModeSwitchRequest(c, Screen, Lock), cookie) + return LockModeSwitchCookie{cookie} +} + +// LockModeSwitchChecked sends a checked request. +// If an error occurs, it can be retrieved using LockModeSwitchCookie.Check() +func LockModeSwitchChecked(c *xgb.Conn, Screen uint16, Lock uint16) LockModeSwitchCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'LockModeSwitch' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(lockModeSwitchRequest(c, Screen, Lock), cookie) + return LockModeSwitchCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook LockModeSwitchCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for LockModeSwitch +// lockModeSwitchRequest writes a LockModeSwitch request to a byte slice. +func lockModeSwitchRequest(c *xgb.Conn, Screen uint16, Lock uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + xgb.Put16(buf[b:], Lock) + b += 2 + + return buf +} + +// ModModeLineCookie is a cookie used only for ModModeLine requests. +type ModModeLineCookie struct { + *xgb.Cookie +} + +// ModModeLine sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ModModeLine(c *xgb.Conn, Screen uint32, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) ModModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'ModModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(modModeLineRequest(c, Screen, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return ModModeLineCookie{cookie} +} + +// ModModeLineChecked sends a checked request. +// If an error occurs, it can be retrieved using ModModeLineCookie.Check() +func ModModeLineChecked(c *xgb.Conn, Screen uint32, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) ModModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'ModModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(modModeLineRequest(c, Screen, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return ModModeLineCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ModModeLineCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ModModeLine +// modModeLineRequest writes a ModModeLine request to a byte slice. +func modModeLineRequest(c *xgb.Conn, Screen uint32, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) []byte { + size := xgb.Pad((48 + xgb.Pad((int(Privsize) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put16(buf[b:], Hdisplay) + b += 2 + + xgb.Put16(buf[b:], Hsyncstart) + b += 2 + + xgb.Put16(buf[b:], Hsyncend) + b += 2 + + xgb.Put16(buf[b:], Htotal) + b += 2 + + xgb.Put16(buf[b:], Hskew) + b += 2 + + xgb.Put16(buf[b:], Vdisplay) + b += 2 + + xgb.Put16(buf[b:], Vsyncstart) + b += 2 + + xgb.Put16(buf[b:], Vsyncend) + b += 2 + + xgb.Put16(buf[b:], Vtotal) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], Flags) + b += 4 + + b += 12 // padding + + xgb.Put32(buf[b:], Privsize) + b += 4 + + copy(buf[b:], Private[:Privsize]) + b += int(Privsize) + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint16 + MinorVersion uint16 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// SetClientVersionCookie is a cookie used only for SetClientVersion requests. +type SetClientVersionCookie struct { + *xgb.Cookie +} + +// SetClientVersion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetClientVersion(c *xgb.Conn, Major uint16, Minor uint16) SetClientVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetClientVersion' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setClientVersionRequest(c, Major, Minor), cookie) + return SetClientVersionCookie{cookie} +} + +// SetClientVersionChecked sends a checked request. +// If an error occurs, it can be retrieved using SetClientVersionCookie.Check() +func SetClientVersionChecked(c *xgb.Conn, Major uint16, Minor uint16) SetClientVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetClientVersion' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setClientVersionRequest(c, Major, Minor), cookie) + return SetClientVersionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetClientVersionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetClientVersion +// setClientVersionRequest writes a SetClientVersion request to a byte slice. +func setClientVersionRequest(c *xgb.Conn, Major uint16, Minor uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Major) + b += 2 + + xgb.Put16(buf[b:], Minor) + b += 2 + + return buf +} + +// SetGammaCookie is a cookie used only for SetGamma requests. +type SetGammaCookie struct { + *xgb.Cookie +} + +// SetGamma sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetGamma(c *xgb.Conn, Screen uint16, Red uint32, Green uint32, Blue uint32) SetGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetGamma' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setGammaRequest(c, Screen, Red, Green, Blue), cookie) + return SetGammaCookie{cookie} +} + +// SetGammaChecked sends a checked request. +// If an error occurs, it can be retrieved using SetGammaCookie.Check() +func SetGammaChecked(c *xgb.Conn, Screen uint16, Red uint32, Green uint32, Blue uint32) SetGammaCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetGamma' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setGammaRequest(c, Screen, Red, Green, Blue), cookie) + return SetGammaCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetGammaCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetGamma +// setGammaRequest writes a SetGamma request to a byte slice. +func setGammaRequest(c *xgb.Conn, Screen uint16, Red uint32, Green uint32, Blue uint32) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], Red) + b += 4 + + xgb.Put32(buf[b:], Green) + b += 4 + + xgb.Put32(buf[b:], Blue) + b += 4 + + b += 12 // padding + + return buf +} + +// SetGammaRampCookie is a cookie used only for SetGammaRamp requests. +type SetGammaRampCookie struct { + *xgb.Cookie +} + +// SetGammaRamp sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetGammaRamp(c *xgb.Conn, Screen uint16, Size uint16, Red []uint16, Green []uint16, Blue []uint16) SetGammaRampCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetGammaRamp' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setGammaRampRequest(c, Screen, Size, Red, Green, Blue), cookie) + return SetGammaRampCookie{cookie} +} + +// SetGammaRampChecked sends a checked request. +// If an error occurs, it can be retrieved using SetGammaRampCookie.Check() +func SetGammaRampChecked(c *xgb.Conn, Screen uint16, Size uint16, Red []uint16, Green []uint16, Blue []uint16) SetGammaRampCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetGammaRamp' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setGammaRampRequest(c, Screen, Size, Red, Green, Blue), cookie) + return SetGammaRampCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetGammaRampCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetGammaRamp +// setGammaRampRequest writes a SetGammaRamp request to a byte slice. +func setGammaRampRequest(c *xgb.Conn, Screen uint16, Size uint16, Red []uint16, Green []uint16, Blue []uint16) []byte { + size := xgb.Pad((((8 + xgb.Pad((((int(Size) + 1) & -2) * 2))) + xgb.Pad((((int(Size) + 1) & -2) * 2))) + xgb.Pad((((int(Size) + 1) & -2) * 2)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + xgb.Put16(buf[b:], Size) + b += 2 + + for i := 0; i < int(((int(Size) + 1) & -2)); i++ { + xgb.Put16(buf[b:], Red[i]) + b += 2 + } + + for i := 0; i < int(((int(Size) + 1) & -2)); i++ { + xgb.Put16(buf[b:], Green[i]) + b += 2 + } + + for i := 0; i < int(((int(Size) + 1) & -2)); i++ { + xgb.Put16(buf[b:], Blue[i]) + b += 2 + } + + return buf +} + +// SetViewPortCookie is a cookie used only for SetViewPort requests. +type SetViewPortCookie struct { + *xgb.Cookie +} + +// SetViewPort sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetViewPort(c *xgb.Conn, Screen uint16, X uint32, Y uint32) SetViewPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetViewPort' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setViewPortRequest(c, Screen, X, Y), cookie) + return SetViewPortCookie{cookie} +} + +// SetViewPortChecked sends a checked request. +// If an error occurs, it can be retrieved using SetViewPortCookie.Check() +func SetViewPortChecked(c *xgb.Conn, Screen uint16, X uint32, Y uint32) SetViewPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SetViewPort' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setViewPortRequest(c, Screen, X, Y), cookie) + return SetViewPortCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetViewPortCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetViewPort +// setViewPortRequest writes a SetViewPort request to a byte slice. +func setViewPortRequest(c *xgb.Conn, Screen uint16, X uint32, Y uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], X) + b += 4 + + xgb.Put32(buf[b:], Y) + b += 4 + + return buf +} + +// SwitchModeCookie is a cookie used only for SwitchMode requests. +type SwitchModeCookie struct { + *xgb.Cookie +} + +// SwitchMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwitchMode(c *xgb.Conn, Screen uint16, Zoom uint16) SwitchModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SwitchMode' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(switchModeRequest(c, Screen, Zoom), cookie) + return SwitchModeCookie{cookie} +} + +// SwitchModeChecked sends a checked request. +// If an error occurs, it can be retrieved using SwitchModeCookie.Check() +func SwitchModeChecked(c *xgb.Conn, Screen uint16, Zoom uint16) SwitchModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SwitchMode' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(switchModeRequest(c, Screen, Zoom), cookie) + return SwitchModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SwitchModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SwitchMode +// switchModeRequest writes a SwitchMode request to a byte slice. +func switchModeRequest(c *xgb.Conn, Screen uint16, Zoom uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], Screen) + b += 2 + + xgb.Put16(buf[b:], Zoom) + b += 2 + + return buf +} + +// SwitchToModeCookie is a cookie used only for SwitchToMode requests. +type SwitchToModeCookie struct { + *xgb.Cookie +} + +// SwitchToMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwitchToMode(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) SwitchToModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SwitchToMode' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(switchToModeRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return SwitchToModeCookie{cookie} +} + +// SwitchToModeChecked sends a checked request. +// If an error occurs, it can be retrieved using SwitchToModeCookie.Check() +func SwitchToModeChecked(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) SwitchToModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'SwitchToMode' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(switchToModeRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return SwitchToModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SwitchToModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SwitchToMode +// switchToModeRequest writes a SwitchToMode request to a byte slice. +func switchToModeRequest(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) []byte { + size := xgb.Pad((52 + xgb.Pad((int(Privsize) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Dotclock)) + b += 4 + + xgb.Put16(buf[b:], Hdisplay) + b += 2 + + xgb.Put16(buf[b:], Hsyncstart) + b += 2 + + xgb.Put16(buf[b:], Hsyncend) + b += 2 + + xgb.Put16(buf[b:], Htotal) + b += 2 + + xgb.Put16(buf[b:], Hskew) + b += 2 + + xgb.Put16(buf[b:], Vdisplay) + b += 2 + + xgb.Put16(buf[b:], Vsyncstart) + b += 2 + + xgb.Put16(buf[b:], Vsyncend) + b += 2 + + xgb.Put16(buf[b:], Vtotal) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], Flags) + b += 4 + + b += 12 // padding + + xgb.Put32(buf[b:], Privsize) + b += 4 + + copy(buf[b:], Private[:Privsize]) + b += int(Privsize) + + return buf +} + +// ValidateModeLineCookie is a cookie used only for ValidateModeLine requests. +type ValidateModeLineCookie struct { + *xgb.Cookie +} + +// ValidateModeLine sends a checked request. +// If an error occurs, it will be returned with the reply by calling ValidateModeLineCookie.Reply() +func ValidateModeLine(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) ValidateModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'ValidateModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(validateModeLineRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return ValidateModeLineCookie{cookie} +} + +// ValidateModeLineUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ValidateModeLineUnchecked(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) ValidateModeLineCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFree86-VidModeExtension"]; !ok { + panic("Cannot issue request 'ValidateModeLine' using the uninitialized extension 'XFree86-VidModeExtension'. xf86vidmode.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(validateModeLineRequest(c, Screen, Dotclock, Hdisplay, Hsyncstart, Hsyncend, Htotal, Hskew, Vdisplay, Vsyncstart, Vsyncend, Vtotal, Flags, Privsize, Private), cookie) + return ValidateModeLineCookie{cookie} +} + +// ValidateModeLineReply represents the data returned from a ValidateModeLine request. +type ValidateModeLineReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Status uint32 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a ValidateModeLine request. +func (cook ValidateModeLineCookie) Reply() (*ValidateModeLineReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return validateModeLineReply(buf), nil +} + +// validateModeLineReply reads a byte slice into a ValidateModeLineReply value. +func validateModeLineReply(buf []byte) *ValidateModeLineReply { + v := new(ValidateModeLineReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Status = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for ValidateModeLine +// validateModeLineRequest writes a ValidateModeLine request to a byte slice. +func validateModeLineRequest(c *xgb.Conn, Screen uint32, Dotclock Dotclock, Hdisplay uint16, Hsyncstart uint16, Hsyncend uint16, Htotal uint16, Hskew uint16, Vdisplay uint16, Vsyncstart uint16, Vsyncend uint16, Vtotal uint16, Flags uint32, Privsize uint32, Private []byte) []byte { + size := xgb.Pad((52 + xgb.Pad((int(Privsize) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFree86-VidModeExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Screen) + b += 4 + + xgb.Put32(buf[b:], uint32(Dotclock)) + b += 4 + + xgb.Put16(buf[b:], Hdisplay) + b += 2 + + xgb.Put16(buf[b:], Hsyncstart) + b += 2 + + xgb.Put16(buf[b:], Hsyncend) + b += 2 + + xgb.Put16(buf[b:], Htotal) + b += 2 + + xgb.Put16(buf[b:], Hskew) + b += 2 + + xgb.Put16(buf[b:], Vdisplay) + b += 2 + + xgb.Put16(buf[b:], Vsyncstart) + b += 2 + + xgb.Put16(buf[b:], Vsyncend) + b += 2 + + xgb.Put16(buf[b:], Vtotal) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], Flags) + b += 4 + + b += 12 // padding + + xgb.Put32(buf[b:], Privsize) + b += 4 + + copy(buf[b:], Private[:Privsize]) + b += int(Privsize) + + return buf +} diff --git a/vend/xgb/xfixes/xfixes.go b/vend/xgb/xfixes/xfixes.go new file mode 100644 index 0000000..42d802d --- /dev/null +++ b/vend/xgb/xfixes/xfixes.go @@ -0,0 +1,2995 @@ +// Package xfixes is the X client API for the XFIXES extension. +package xfixes + +// This file is automatically generated from xfixes.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/render" + "github.com/jezek/xgb/shape" + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XFIXES extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 6, "XFIXES").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XFIXES could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XFIXES"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XFIXES"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XFIXES"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XFIXES"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XFIXES"] = make(map[int]xgb.NewErrorFun) +} + +// BadBadRegion is the error number for a BadBadRegion. +const BadBadRegion = 0 + +type BadRegionError struct { + Sequence uint16 + NiceName string +} + +// BadRegionErrorNew constructs a BadRegionError value that implements xgb.Error from a byte slice. +func BadRegionErrorNew(buf []byte) xgb.Error { + v := BadRegionError{} + v.NiceName = "BadRegion" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadRegion error. +// This is mostly used internally. +func (err BadRegionError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadRegion error. If no bad value exists, 0 is returned. +func (err BadRegionError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadRegion error. + +func (err BadRegionError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadRegion {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XFIXES"][0] = BadRegionErrorNew +} + +type Barrier uint32 + +func NewBarrierId(c *xgb.Conn) (Barrier, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Barrier(id), nil +} + +const ( + BarrierDirectionsPositiveX = 1 + BarrierDirectionsPositiveY = 2 + BarrierDirectionsNegativeX = 4 + BarrierDirectionsNegativeY = 8 +) + +const ( + ClientDisconnectFlagsDefault = 0 + ClientDisconnectFlagsTerminate = 1 +) + +// CursorNotify is the event number for a CursorNotifyEvent. +const CursorNotify = 1 + +type CursorNotifyEvent struct { + Sequence uint16 + Subtype byte + Window xproto.Window + CursorSerial uint32 + Timestamp xproto.Timestamp + Name xproto.Atom + // padding: 12 bytes +} + +// CursorNotifyEventNew constructs a CursorNotifyEvent value that implements xgb.Event from a byte slice. +func CursorNotifyEventNew(buf []byte) xgb.Event { + v := CursorNotifyEvent{} + b := 1 // don't read event number + + v.Subtype = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.CursorSerial = xgb.Get32(buf[b:]) + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Name = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + b += 12 // padding + + return v +} + +// Bytes writes a CursorNotifyEvent value to a byte slice. +func (v CursorNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 1 + b += 1 + + buf[b] = v.Subtype + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], v.CursorSerial) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Name)) + b += 4 + + b += 12 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the CursorNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v CursorNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of CursorNotifyEvent. +func (v CursorNotifyEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Subtype: %d", v.Subtype)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("CursorSerial: %d", v.CursorSerial)) + fieldVals = append(fieldVals, xgb.Sprintf("Timestamp: %d", v.Timestamp)) + fieldVals = append(fieldVals, xgb.Sprintf("Name: %d", v.Name)) + return "CursorNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["XFIXES"][1] = CursorNotifyEventNew +} + +const ( + CursorNotifyDisplayCursor = 0 +) + +const ( + CursorNotifyMaskDisplayCursor = 1 +) + +type Region uint32 + +func NewRegionId(c *xgb.Conn) (Region, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Region(id), nil +} + +const ( + RegionNone = 0 +) + +const ( + SaveSetMappingMap = 0 + SaveSetMappingUnmap = 1 +) + +const ( + SaveSetModeInsert = 0 + SaveSetModeDelete = 1 +) + +const ( + SaveSetTargetNearest = 0 + SaveSetTargetRoot = 1 +) + +const ( + SelectionEventSetSelectionOwner = 0 + SelectionEventSelectionWindowDestroy = 1 + SelectionEventSelectionClientClose = 2 +) + +const ( + SelectionEventMaskSetSelectionOwner = 1 + SelectionEventMaskSelectionWindowDestroy = 2 + SelectionEventMaskSelectionClientClose = 4 +) + +// SelectionNotify is the event number for a SelectionNotifyEvent. +const SelectionNotify = 0 + +type SelectionNotifyEvent struct { + Sequence uint16 + Subtype byte + Window xproto.Window + Owner xproto.Window + Selection xproto.Atom + Timestamp xproto.Timestamp + SelectionTimestamp xproto.Timestamp + // padding: 8 bytes +} + +// SelectionNotifyEventNew constructs a SelectionNotifyEvent value that implements xgb.Event from a byte slice. +func SelectionNotifyEventNew(buf []byte) xgb.Event { + v := SelectionNotifyEvent{} + b := 1 // don't read event number + + v.Subtype = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Owner = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Selection = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.SelectionTimestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + b += 8 // padding + + return v +} + +// Bytes writes a SelectionNotifyEvent value to a byte slice. +func (v SelectionNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = v.Subtype + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Owner)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Selection)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.SelectionTimestamp)) + b += 4 + + b += 8 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the SelectionNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v SelectionNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of SelectionNotifyEvent. +func (v SelectionNotifyEvent) String() string { + fieldVals := make([]string, 0, 7) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Subtype: %d", v.Subtype)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Owner: %d", v.Owner)) + fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection)) + fieldVals = append(fieldVals, xgb.Sprintf("Timestamp: %d", v.Timestamp)) + fieldVals = append(fieldVals, xgb.Sprintf("SelectionTimestamp: %d", v.SelectionTimestamp)) + return "SelectionNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["XFIXES"][0] = SelectionNotifyEventNew +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// ChangeCursorCookie is a cookie used only for ChangeCursor requests. +type ChangeCursorCookie struct { + *xgb.Cookie +} + +// ChangeCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeCursor(c *xgb.Conn, Source xproto.Cursor, Destination xproto.Cursor) ChangeCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ChangeCursor' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changeCursorRequest(c, Source, Destination), cookie) + return ChangeCursorCookie{cookie} +} + +// ChangeCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeCursorCookie.Check() +func ChangeCursorChecked(c *xgb.Conn, Source xproto.Cursor, Destination xproto.Cursor) ChangeCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ChangeCursor' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changeCursorRequest(c, Source, Destination), cookie) + return ChangeCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeCursor +// changeCursorRequest writes a ChangeCursor request to a byte slice. +func changeCursorRequest(c *xgb.Conn, Source xproto.Cursor, Destination xproto.Cursor) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 26 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} + +// ChangeCursorByNameCookie is a cookie used only for ChangeCursorByName requests. +type ChangeCursorByNameCookie struct { + *xgb.Cookie +} + +// ChangeCursorByName sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeCursorByName(c *xgb.Conn, Src xproto.Cursor, Nbytes uint16, Name string) ChangeCursorByNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ChangeCursorByName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changeCursorByNameRequest(c, Src, Nbytes, Name), cookie) + return ChangeCursorByNameCookie{cookie} +} + +// ChangeCursorByNameChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeCursorByNameCookie.Check() +func ChangeCursorByNameChecked(c *xgb.Conn, Src xproto.Cursor, Nbytes uint16, Name string) ChangeCursorByNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ChangeCursorByName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changeCursorByNameRequest(c, Src, Nbytes, Name), cookie) + return ChangeCursorByNameCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeCursorByNameCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeCursorByName +// changeCursorByNameRequest writes a ChangeCursorByName request to a byte slice. +func changeCursorByNameRequest(c *xgb.Conn, Src xproto.Cursor, Nbytes uint16, Name string) []byte { + size := xgb.Pad((12 + xgb.Pad((int(Nbytes) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 27 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Src)) + b += 4 + + xgb.Put16(buf[b:], Nbytes) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:Nbytes]) + b += int(Nbytes) + + return buf +} + +// ChangeSaveSetCookie is a cookie used only for ChangeSaveSet requests. +type ChangeSaveSetCookie struct { + *xgb.Cookie +} + +// ChangeSaveSet sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeSaveSet(c *xgb.Conn, Mode byte, Target byte, Map byte, Window xproto.Window) ChangeSaveSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ChangeSaveSet' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(changeSaveSetRequest(c, Mode, Target, Map, Window), cookie) + return ChangeSaveSetCookie{cookie} +} + +// ChangeSaveSetChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeSaveSetCookie.Check() +func ChangeSaveSetChecked(c *xgb.Conn, Mode byte, Target byte, Map byte, Window xproto.Window) ChangeSaveSetCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ChangeSaveSet' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(changeSaveSetRequest(c, Mode, Target, Map, Window), cookie) + return ChangeSaveSetCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeSaveSetCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeSaveSet +// changeSaveSetRequest writes a ChangeSaveSet request to a byte slice. +func changeSaveSetRequest(c *xgb.Conn, Mode byte, Target byte, Map byte, Window xproto.Window) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Mode + b += 1 + + buf[b] = Target + b += 1 + + buf[b] = Map + b += 1 + + b += 1 // padding + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// CopyRegionCookie is a cookie used only for CopyRegion requests. +type CopyRegionCookie struct { + *xgb.Cookie +} + +// CopyRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyRegion(c *xgb.Conn, Source Region, Destination Region) CopyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CopyRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(copyRegionRequest(c, Source, Destination), cookie) + return CopyRegionCookie{cookie} +} + +// CopyRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using CopyRegionCookie.Check() +func CopyRegionChecked(c *xgb.Conn, Source Region, Destination Region) CopyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CopyRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(copyRegionRequest(c, Source, Destination), cookie) + return CopyRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CopyRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CopyRegion +// copyRegionRequest writes a CopyRegion request to a byte slice. +func copyRegionRequest(c *xgb.Conn, Source Region, Destination Region) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} + +// CreatePointerBarrierCookie is a cookie used only for CreatePointerBarrier requests. +type CreatePointerBarrierCookie struct { + *xgb.Cookie +} + +// CreatePointerBarrier sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreatePointerBarrier(c *xgb.Conn, Barrier Barrier, Window xproto.Window, X1 uint16, Y1 uint16, X2 uint16, Y2 uint16, Directions uint32, NumDevices uint16, Devices []uint16) CreatePointerBarrierCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreatePointerBarrier' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createPointerBarrierRequest(c, Barrier, Window, X1, Y1, X2, Y2, Directions, NumDevices, Devices), cookie) + return CreatePointerBarrierCookie{cookie} +} + +// CreatePointerBarrierChecked sends a checked request. +// If an error occurs, it can be retrieved using CreatePointerBarrierCookie.Check() +func CreatePointerBarrierChecked(c *xgb.Conn, Barrier Barrier, Window xproto.Window, X1 uint16, Y1 uint16, X2 uint16, Y2 uint16, Directions uint32, NumDevices uint16, Devices []uint16) CreatePointerBarrierCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreatePointerBarrier' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createPointerBarrierRequest(c, Barrier, Window, X1, Y1, X2, Y2, Directions, NumDevices, Devices), cookie) + return CreatePointerBarrierCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreatePointerBarrierCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreatePointerBarrier +// createPointerBarrierRequest writes a CreatePointerBarrier request to a byte slice. +func createPointerBarrierRequest(c *xgb.Conn, Barrier Barrier, Window xproto.Window, X1 uint16, Y1 uint16, X2 uint16, Y2 uint16, Directions uint32, NumDevices uint16, Devices []uint16) []byte { + size := xgb.Pad((28 + xgb.Pad((int(NumDevices) * 2)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 31 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Barrier)) + b += 4 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put16(buf[b:], X1) + b += 2 + + xgb.Put16(buf[b:], Y1) + b += 2 + + xgb.Put16(buf[b:], X2) + b += 2 + + xgb.Put16(buf[b:], Y2) + b += 2 + + xgb.Put32(buf[b:], Directions) + b += 4 + + b += 2 // padding + + xgb.Put16(buf[b:], NumDevices) + b += 2 + + for i := 0; i < int(NumDevices); i++ { + xgb.Put16(buf[b:], Devices[i]) + b += 2 + } + + return buf +} + +// CreateRegionCookie is a cookie used only for CreateRegion requests. +type CreateRegionCookie struct { + *xgb.Cookie +} + +// CreateRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRegion(c *xgb.Conn, Region Region, Rectangles []xproto.Rectangle) CreateRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRegionRequest(c, Region, Rectangles), cookie) + return CreateRegionCookie{cookie} +} + +// CreateRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRegionCookie.Check() +func CreateRegionChecked(c *xgb.Conn, Region Region, Rectangles []xproto.Rectangle) CreateRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRegionRequest(c, Region, Rectangles), cookie) + return CreateRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRegion +// createRegionRequest writes a CreateRegion request to a byte slice. +func createRegionRequest(c *xgb.Conn, Region Region, Rectangles []xproto.Rectangle) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + b += xproto.RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// CreateRegionFromBitmapCookie is a cookie used only for CreateRegionFromBitmap requests. +type CreateRegionFromBitmapCookie struct { + *xgb.Cookie +} + +// CreateRegionFromBitmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRegionFromBitmap(c *xgb.Conn, Region Region, Bitmap xproto.Pixmap) CreateRegionFromBitmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromBitmap' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRegionFromBitmapRequest(c, Region, Bitmap), cookie) + return CreateRegionFromBitmapCookie{cookie} +} + +// CreateRegionFromBitmapChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRegionFromBitmapCookie.Check() +func CreateRegionFromBitmapChecked(c *xgb.Conn, Region Region, Bitmap xproto.Pixmap) CreateRegionFromBitmapCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromBitmap' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRegionFromBitmapRequest(c, Region, Bitmap), cookie) + return CreateRegionFromBitmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRegionFromBitmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRegionFromBitmap +// createRegionFromBitmapRequest writes a CreateRegionFromBitmap request to a byte slice. +func createRegionFromBitmapRequest(c *xgb.Conn, Region Region, Bitmap xproto.Pixmap) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put32(buf[b:], uint32(Bitmap)) + b += 4 + + return buf +} + +// CreateRegionFromGCCookie is a cookie used only for CreateRegionFromGC requests. +type CreateRegionFromGCCookie struct { + *xgb.Cookie +} + +// CreateRegionFromGC sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRegionFromGC(c *xgb.Conn, Region Region, Gc xproto.Gcontext) CreateRegionFromGCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromGC' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRegionFromGCRequest(c, Region, Gc), cookie) + return CreateRegionFromGCCookie{cookie} +} + +// CreateRegionFromGCChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRegionFromGCCookie.Check() +func CreateRegionFromGCChecked(c *xgb.Conn, Region Region, Gc xproto.Gcontext) CreateRegionFromGCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromGC' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRegionFromGCRequest(c, Region, Gc), cookie) + return CreateRegionFromGCCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRegionFromGCCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRegionFromGC +// createRegionFromGCRequest writes a CreateRegionFromGC request to a byte slice. +func createRegionFromGCRequest(c *xgb.Conn, Region Region, Gc xproto.Gcontext) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + return buf +} + +// CreateRegionFromPictureCookie is a cookie used only for CreateRegionFromPicture requests. +type CreateRegionFromPictureCookie struct { + *xgb.Cookie +} + +// CreateRegionFromPicture sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRegionFromPicture(c *xgb.Conn, Region Region, Picture render.Picture) CreateRegionFromPictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromPicture' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRegionFromPictureRequest(c, Region, Picture), cookie) + return CreateRegionFromPictureCookie{cookie} +} + +// CreateRegionFromPictureChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRegionFromPictureCookie.Check() +func CreateRegionFromPictureChecked(c *xgb.Conn, Region Region, Picture render.Picture) CreateRegionFromPictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromPicture' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRegionFromPictureRequest(c, Region, Picture), cookie) + return CreateRegionFromPictureCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRegionFromPictureCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRegionFromPicture +// createRegionFromPictureRequest writes a CreateRegionFromPicture request to a byte slice. +func createRegionFromPictureRequest(c *xgb.Conn, Region Region, Picture render.Picture) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + return buf +} + +// CreateRegionFromWindowCookie is a cookie used only for CreateRegionFromWindow requests. +type CreateRegionFromWindowCookie struct { + *xgb.Cookie +} + +// CreateRegionFromWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateRegionFromWindow(c *xgb.Conn, Region Region, Window xproto.Window, Kind shape.Kind) CreateRegionFromWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromWindow' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createRegionFromWindowRequest(c, Region, Window, Kind), cookie) + return CreateRegionFromWindowCookie{cookie} +} + +// CreateRegionFromWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateRegionFromWindowCookie.Check() +func CreateRegionFromWindowChecked(c *xgb.Conn, Region Region, Window xproto.Window, Kind shape.Kind) CreateRegionFromWindowCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'CreateRegionFromWindow' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createRegionFromWindowRequest(c, Region, Window, Kind), cookie) + return CreateRegionFromWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateRegionFromWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateRegionFromWindow +// createRegionFromWindowRequest writes a CreateRegionFromWindow request to a byte slice. +func createRegionFromWindowRequest(c *xgb.Conn, Region Region, Window xproto.Window, Kind shape.Kind) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + buf[b] = byte(Kind) + b += 1 + + b += 3 // padding + + return buf +} + +// DeletePointerBarrierCookie is a cookie used only for DeletePointerBarrier requests. +type DeletePointerBarrierCookie struct { + *xgb.Cookie +} + +// DeletePointerBarrier sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeletePointerBarrier(c *xgb.Conn, Barrier Barrier) DeletePointerBarrierCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'DeletePointerBarrier' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deletePointerBarrierRequest(c, Barrier), cookie) + return DeletePointerBarrierCookie{cookie} +} + +// DeletePointerBarrierChecked sends a checked request. +// If an error occurs, it can be retrieved using DeletePointerBarrierCookie.Check() +func DeletePointerBarrierChecked(c *xgb.Conn, Barrier Barrier) DeletePointerBarrierCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'DeletePointerBarrier' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deletePointerBarrierRequest(c, Barrier), cookie) + return DeletePointerBarrierCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeletePointerBarrierCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeletePointerBarrier +// deletePointerBarrierRequest writes a DeletePointerBarrier request to a byte slice. +func deletePointerBarrierRequest(c *xgb.Conn, Barrier Barrier) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 32 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Barrier)) + b += 4 + + return buf +} + +// DestroyRegionCookie is a cookie used only for DestroyRegion requests. +type DestroyRegionCookie struct { + *xgb.Cookie +} + +// DestroyRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyRegion(c *xgb.Conn, Region Region) DestroyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'DestroyRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyRegionRequest(c, Region), cookie) + return DestroyRegionCookie{cookie} +} + +// DestroyRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyRegionCookie.Check() +func DestroyRegionChecked(c *xgb.Conn, Region Region) DestroyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'DestroyRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyRegionRequest(c, Region), cookie) + return DestroyRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyRegion +// destroyRegionRequest writes a DestroyRegion request to a byte slice. +func destroyRegionRequest(c *xgb.Conn, Region Region) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + return buf +} + +// ExpandRegionCookie is a cookie used only for ExpandRegion requests. +type ExpandRegionCookie struct { + *xgb.Cookie +} + +// ExpandRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ExpandRegion(c *xgb.Conn, Source Region, Destination Region, Left uint16, Right uint16, Top uint16, Bottom uint16) ExpandRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ExpandRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(expandRegionRequest(c, Source, Destination, Left, Right, Top, Bottom), cookie) + return ExpandRegionCookie{cookie} +} + +// ExpandRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using ExpandRegionCookie.Check() +func ExpandRegionChecked(c *xgb.Conn, Source Region, Destination Region, Left uint16, Right uint16, Top uint16, Bottom uint16) ExpandRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ExpandRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(expandRegionRequest(c, Source, Destination, Left, Right, Top, Bottom), cookie) + return ExpandRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ExpandRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ExpandRegion +// expandRegionRequest writes a ExpandRegion request to a byte slice. +func expandRegionRequest(c *xgb.Conn, Source Region, Destination Region, Left uint16, Right uint16, Top uint16, Bottom uint16) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 28 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + xgb.Put16(buf[b:], Left) + b += 2 + + xgb.Put16(buf[b:], Right) + b += 2 + + xgb.Put16(buf[b:], Top) + b += 2 + + xgb.Put16(buf[b:], Bottom) + b += 2 + + return buf +} + +// FetchRegionCookie is a cookie used only for FetchRegion requests. +type FetchRegionCookie struct { + *xgb.Cookie +} + +// FetchRegion sends a checked request. +// If an error occurs, it will be returned with the reply by calling FetchRegionCookie.Reply() +func FetchRegion(c *xgb.Conn, Region Region) FetchRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'FetchRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(fetchRegionRequest(c, Region), cookie) + return FetchRegionCookie{cookie} +} + +// FetchRegionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FetchRegionUnchecked(c *xgb.Conn, Region Region) FetchRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'FetchRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(fetchRegionRequest(c, Region), cookie) + return FetchRegionCookie{cookie} +} + +// FetchRegionReply represents the data returned from a FetchRegion request. +type FetchRegionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Extents xproto.Rectangle + // padding: 16 bytes + Rectangles []xproto.Rectangle // size: xgb.Pad(((int(Length) / 2) * 8)) +} + +// Reply blocks and returns the reply data for a FetchRegion request. +func (cook FetchRegionCookie) Reply() (*FetchRegionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return fetchRegionReply(buf), nil +} + +// fetchRegionReply reads a byte slice into a FetchRegionReply value. +func fetchRegionReply(buf []byte) *FetchRegionReply { + v := new(FetchRegionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Extents = xproto.Rectangle{} + b += xproto.RectangleRead(buf[b:], &v.Extents) + + b += 16 // padding + + v.Rectangles = make([]xproto.Rectangle, (int(v.Length) / 2)) + b += xproto.RectangleReadList(buf[b:], v.Rectangles) + + return v +} + +// Write request to wire for FetchRegion +// fetchRegionRequest writes a FetchRegion request to a byte slice. +func fetchRegionRequest(c *xgb.Conn, Region Region) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + return buf +} + +// GetClientDisconnectModeCookie is a cookie used only for GetClientDisconnectMode requests. +type GetClientDisconnectModeCookie struct { + *xgb.Cookie +} + +// GetClientDisconnectMode sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetClientDisconnectModeCookie.Reply() +func GetClientDisconnectMode(c *xgb.Conn) GetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getClientDisconnectModeRequest(c), cookie) + return GetClientDisconnectModeCookie{cookie} +} + +// GetClientDisconnectModeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetClientDisconnectModeUnchecked(c *xgb.Conn) GetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getClientDisconnectModeRequest(c), cookie) + return GetClientDisconnectModeCookie{cookie} +} + +// GetClientDisconnectModeReply represents the data returned from a GetClientDisconnectMode request. +type GetClientDisconnectModeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + DisconnectMode uint32 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a GetClientDisconnectMode request. +func (cook GetClientDisconnectModeCookie) Reply() (*GetClientDisconnectModeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getClientDisconnectModeReply(buf), nil +} + +// getClientDisconnectModeReply reads a byte slice into a GetClientDisconnectModeReply value. +func getClientDisconnectModeReply(buf []byte) *GetClientDisconnectModeReply { + v := new(GetClientDisconnectModeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.DisconnectMode = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for GetClientDisconnectMode +// getClientDisconnectModeRequest writes a GetClientDisconnectMode request to a byte slice. +func getClientDisconnectModeRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 34 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetCursorImageCookie is a cookie used only for GetCursorImage requests. +type GetCursorImageCookie struct { + *xgb.Cookie +} + +// GetCursorImage sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCursorImageCookie.Reply() +func GetCursorImage(c *xgb.Conn) GetCursorImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetCursorImage' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCursorImageRequest(c), cookie) + return GetCursorImageCookie{cookie} +} + +// GetCursorImageUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCursorImageUnchecked(c *xgb.Conn) GetCursorImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetCursorImage' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCursorImageRequest(c), cookie) + return GetCursorImageCookie{cookie} +} + +// GetCursorImageReply represents the data returned from a GetCursorImage request. +type GetCursorImageReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + X int16 + Y int16 + Width uint16 + Height uint16 + Xhot uint16 + Yhot uint16 + CursorSerial uint32 + // padding: 8 bytes + CursorImage []uint32 // size: xgb.Pad(((int(Width) * int(Height)) * 4)) +} + +// Reply blocks and returns the reply data for a GetCursorImage request. +func (cook GetCursorImageCookie) Reply() (*GetCursorImageReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCursorImageReply(buf), nil +} + +// getCursorImageReply reads a byte slice into a GetCursorImageReply value. +func getCursorImageReply(buf []byte) *GetCursorImageReply { + v := new(GetCursorImageReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Xhot = xgb.Get16(buf[b:]) + b += 2 + + v.Yhot = xgb.Get16(buf[b:]) + b += 2 + + v.CursorSerial = xgb.Get32(buf[b:]) + b += 4 + + b += 8 // padding + + v.CursorImage = make([]uint32, (int(v.Width) * int(v.Height))) + for i := 0; i < int((int(v.Width) * int(v.Height))); i++ { + v.CursorImage[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for GetCursorImage +// getCursorImageRequest writes a GetCursorImage request to a byte slice. +func getCursorImageRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetCursorImageAndNameCookie is a cookie used only for GetCursorImageAndName requests. +type GetCursorImageAndNameCookie struct { + *xgb.Cookie +} + +// GetCursorImageAndName sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCursorImageAndNameCookie.Reply() +func GetCursorImageAndName(c *xgb.Conn) GetCursorImageAndNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetCursorImageAndName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCursorImageAndNameRequest(c), cookie) + return GetCursorImageAndNameCookie{cookie} +} + +// GetCursorImageAndNameUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCursorImageAndNameUnchecked(c *xgb.Conn) GetCursorImageAndNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetCursorImageAndName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCursorImageAndNameRequest(c), cookie) + return GetCursorImageAndNameCookie{cookie} +} + +// GetCursorImageAndNameReply represents the data returned from a GetCursorImageAndName request. +type GetCursorImageAndNameReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + X int16 + Y int16 + Width uint16 + Height uint16 + Xhot uint16 + Yhot uint16 + CursorSerial uint32 + CursorAtom xproto.Atom + Nbytes uint16 + // padding: 2 bytes + CursorImage []uint32 // size: xgb.Pad(((int(Width) * int(Height)) * 4)) + Name string // size: xgb.Pad((int(Nbytes) * 1)) +} + +// Reply blocks and returns the reply data for a GetCursorImageAndName request. +func (cook GetCursorImageAndNameCookie) Reply() (*GetCursorImageAndNameReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCursorImageAndNameReply(buf), nil +} + +// getCursorImageAndNameReply reads a byte slice into a GetCursorImageAndNameReply value. +func getCursorImageAndNameReply(buf []byte) *GetCursorImageAndNameReply { + v := new(GetCursorImageAndNameReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Xhot = xgb.Get16(buf[b:]) + b += 2 + + v.Yhot = xgb.Get16(buf[b:]) + b += 2 + + v.CursorSerial = xgb.Get32(buf[b:]) + b += 4 + + v.CursorAtom = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Nbytes = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.CursorImage = make([]uint32, (int(v.Width) * int(v.Height))) + for i := 0; i < int((int(v.Width) * int(v.Height))); i++ { + v.CursorImage[i] = xgb.Get32(buf[b:]) + b += 4 + } + + { + byteString := make([]byte, v.Nbytes) + copy(byteString[:v.Nbytes], buf[b:]) + v.Name = string(byteString) + b += int(v.Nbytes) + } + + return v +} + +// Write request to wire for GetCursorImageAndName +// getCursorImageAndNameRequest writes a GetCursorImageAndName request to a byte slice. +func getCursorImageAndNameRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 25 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetCursorNameCookie is a cookie used only for GetCursorName requests. +type GetCursorNameCookie struct { + *xgb.Cookie +} + +// GetCursorName sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetCursorNameCookie.Reply() +func GetCursorName(c *xgb.Conn, Cursor xproto.Cursor) GetCursorNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetCursorName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getCursorNameRequest(c, Cursor), cookie) + return GetCursorNameCookie{cookie} +} + +// GetCursorNameUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetCursorNameUnchecked(c *xgb.Conn, Cursor xproto.Cursor) GetCursorNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetCursorName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getCursorNameRequest(c, Cursor), cookie) + return GetCursorNameCookie{cookie} +} + +// GetCursorNameReply represents the data returned from a GetCursorName request. +type GetCursorNameReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Atom xproto.Atom + Nbytes uint16 + // padding: 18 bytes + Name string // size: xgb.Pad((int(Nbytes) * 1)) +} + +// Reply blocks and returns the reply data for a GetCursorName request. +func (cook GetCursorNameCookie) Reply() (*GetCursorNameReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getCursorNameReply(buf), nil +} + +// getCursorNameReply reads a byte slice into a GetCursorNameReply value. +func getCursorNameReply(buf []byte) *GetCursorNameReply { + v := new(GetCursorNameReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Atom = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Nbytes = xgb.Get16(buf[b:]) + b += 2 + + b += 18 // padding + + { + byteString := make([]byte, v.Nbytes) + copy(byteString[:v.Nbytes], buf[b:]) + v.Name = string(byteString) + b += int(v.Nbytes) + } + + return v +} + +// Write request to wire for GetCursorName +// getCursorNameRequest writes a GetCursorName request to a byte slice. +func getCursorNameRequest(c *xgb.Conn, Cursor xproto.Cursor) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 24 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + return buf +} + +// HideCursorCookie is a cookie used only for HideCursor requests. +type HideCursorCookie struct { + *xgb.Cookie +} + +// HideCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func HideCursor(c *xgb.Conn, Window xproto.Window) HideCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'HideCursor' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(hideCursorRequest(c, Window), cookie) + return HideCursorCookie{cookie} +} + +// HideCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using HideCursorCookie.Check() +func HideCursorChecked(c *xgb.Conn, Window xproto.Window) HideCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'HideCursor' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(hideCursorRequest(c, Window), cookie) + return HideCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook HideCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for HideCursor +// hideCursorRequest writes a HideCursor request to a byte slice. +func hideCursorRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 29 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// IntersectRegionCookie is a cookie used only for IntersectRegion requests. +type IntersectRegionCookie struct { + *xgb.Cookie +} + +// IntersectRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IntersectRegion(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) IntersectRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'IntersectRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(intersectRegionRequest(c, Source1, Source2, Destination), cookie) + return IntersectRegionCookie{cookie} +} + +// IntersectRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using IntersectRegionCookie.Check() +func IntersectRegionChecked(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) IntersectRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'IntersectRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(intersectRegionRequest(c, Source1, Source2, Destination), cookie) + return IntersectRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook IntersectRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for IntersectRegion +// intersectRegionRequest writes a IntersectRegion request to a byte slice. +func intersectRegionRequest(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source1)) + b += 4 + + xgb.Put32(buf[b:], uint32(Source2)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} + +// InvertRegionCookie is a cookie used only for InvertRegion requests. +type InvertRegionCookie struct { + *xgb.Cookie +} + +// InvertRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func InvertRegion(c *xgb.Conn, Source Region, Bounds xproto.Rectangle, Destination Region) InvertRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'InvertRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(invertRegionRequest(c, Source, Bounds, Destination), cookie) + return InvertRegionCookie{cookie} +} + +// InvertRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using InvertRegionCookie.Check() +func InvertRegionChecked(c *xgb.Conn, Source Region, Bounds xproto.Rectangle, Destination Region) InvertRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'InvertRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(invertRegionRequest(c, Source, Bounds, Destination), cookie) + return InvertRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook InvertRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for InvertRegion +// invertRegionRequest writes a InvertRegion request to a byte slice. +func invertRegionRequest(c *xgb.Conn, Source Region, Bounds xproto.Rectangle, Destination Region) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + { + structBytes := Bounds.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint32 + MinorVersion uint32 + // padding: 16 bytes +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get32(buf[b:]) + b += 4 + + v.MinorVersion = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ClientMajorVersion) + b += 4 + + xgb.Put32(buf[b:], ClientMinorVersion) + b += 4 + + return buf +} + +// RegionExtentsCookie is a cookie used only for RegionExtents requests. +type RegionExtentsCookie struct { + *xgb.Cookie +} + +// RegionExtents sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RegionExtents(c *xgb.Conn, Source Region, Destination Region) RegionExtentsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'RegionExtents' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(regionExtentsRequest(c, Source, Destination), cookie) + return RegionExtentsCookie{cookie} +} + +// RegionExtentsChecked sends a checked request. +// If an error occurs, it can be retrieved using RegionExtentsCookie.Check() +func RegionExtentsChecked(c *xgb.Conn, Source Region, Destination Region) RegionExtentsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'RegionExtents' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(regionExtentsRequest(c, Source, Destination), cookie) + return RegionExtentsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RegionExtentsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RegionExtents +// regionExtentsRequest writes a RegionExtents request to a byte slice. +func regionExtentsRequest(c *xgb.Conn, Source Region, Destination Region) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} + +// SelectCursorInputCookie is a cookie used only for SelectCursorInput requests. +type SelectCursorInputCookie struct { + *xgb.Cookie +} + +// SelectCursorInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectCursorInput(c *xgb.Conn, Window xproto.Window, EventMask uint32) SelectCursorInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SelectCursorInput' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectCursorInputRequest(c, Window, EventMask), cookie) + return SelectCursorInputCookie{cookie} +} + +// SelectCursorInputChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectCursorInputCookie.Check() +func SelectCursorInputChecked(c *xgb.Conn, Window xproto.Window, EventMask uint32) SelectCursorInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SelectCursorInput' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectCursorInputRequest(c, Window, EventMask), cookie) + return SelectCursorInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectCursorInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectCursorInput +// selectCursorInputRequest writes a SelectCursorInput request to a byte slice. +func selectCursorInputRequest(c *xgb.Conn, Window xproto.Window, EventMask uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], EventMask) + b += 4 + + return buf +} + +// SelectSelectionInputCookie is a cookie used only for SelectSelectionInput requests. +type SelectSelectionInputCookie struct { + *xgb.Cookie +} + +// SelectSelectionInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectSelectionInput(c *xgb.Conn, Window xproto.Window, Selection xproto.Atom, EventMask uint32) SelectSelectionInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SelectSelectionInput' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectSelectionInputRequest(c, Window, Selection, EventMask), cookie) + return SelectSelectionInputCookie{cookie} +} + +// SelectSelectionInputChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectSelectionInputCookie.Check() +func SelectSelectionInputChecked(c *xgb.Conn, Window xproto.Window, Selection xproto.Atom, EventMask uint32) SelectSelectionInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SelectSelectionInput' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectSelectionInputRequest(c, Window, Selection, EventMask), cookie) + return SelectSelectionInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectSelectionInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectSelectionInput +// selectSelectionInputRequest writes a SelectSelectionInput request to a byte slice. +func selectSelectionInputRequest(c *xgb.Conn, Window xproto.Window, Selection xproto.Atom, EventMask uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Selection)) + b += 4 + + xgb.Put32(buf[b:], EventMask) + b += 4 + + return buf +} + +// SetClientDisconnectModeCookie is a cookie used only for SetClientDisconnectMode requests. +type SetClientDisconnectModeCookie struct { + *xgb.Cookie +} + +// SetClientDisconnectMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetClientDisconnectMode(c *xgb.Conn, DisconnectMode uint32) SetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setClientDisconnectModeRequest(c, DisconnectMode), cookie) + return SetClientDisconnectModeCookie{cookie} +} + +// SetClientDisconnectModeChecked sends a checked request. +// If an error occurs, it can be retrieved using SetClientDisconnectModeCookie.Check() +func SetClientDisconnectModeChecked(c *xgb.Conn, DisconnectMode uint32) SetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setClientDisconnectModeRequest(c, DisconnectMode), cookie) + return SetClientDisconnectModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetClientDisconnectModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetClientDisconnectMode +// setClientDisconnectModeRequest writes a SetClientDisconnectMode request to a byte slice. +func setClientDisconnectModeRequest(c *xgb.Conn, DisconnectMode uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 33 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], DisconnectMode) + b += 4 + + return buf +} + +// SetCursorNameCookie is a cookie used only for SetCursorName requests. +type SetCursorNameCookie struct { + *xgb.Cookie +} + +// SetCursorName sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetCursorName(c *xgb.Conn, Cursor xproto.Cursor, Nbytes uint16, Name string) SetCursorNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetCursorName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setCursorNameRequest(c, Cursor, Nbytes, Name), cookie) + return SetCursorNameCookie{cookie} +} + +// SetCursorNameChecked sends a checked request. +// If an error occurs, it can be retrieved using SetCursorNameCookie.Check() +func SetCursorNameChecked(c *xgb.Conn, Cursor xproto.Cursor, Nbytes uint16, Name string) SetCursorNameCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetCursorName' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setCursorNameRequest(c, Cursor, Nbytes, Name), cookie) + return SetCursorNameCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetCursorNameCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetCursorName +// setCursorNameRequest writes a SetCursorName request to a byte slice. +func setCursorNameRequest(c *xgb.Conn, Cursor xproto.Cursor, Nbytes uint16, Name string) []byte { + size := xgb.Pad((12 + xgb.Pad((int(Nbytes) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 23 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + xgb.Put16(buf[b:], Nbytes) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:Nbytes]) + b += int(Nbytes) + + return buf +} + +// SetGCClipRegionCookie is a cookie used only for SetGCClipRegion requests. +type SetGCClipRegionCookie struct { + *xgb.Cookie +} + +// SetGCClipRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetGCClipRegion(c *xgb.Conn, Gc xproto.Gcontext, Region Region, XOrigin int16, YOrigin int16) SetGCClipRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetGCClipRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setGCClipRegionRequest(c, Gc, Region, XOrigin, YOrigin), cookie) + return SetGCClipRegionCookie{cookie} +} + +// SetGCClipRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using SetGCClipRegionCookie.Check() +func SetGCClipRegionChecked(c *xgb.Conn, Gc xproto.Gcontext, Region Region, XOrigin int16, YOrigin int16) SetGCClipRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetGCClipRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setGCClipRegionRequest(c, Gc, Region, XOrigin, YOrigin), cookie) + return SetGCClipRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetGCClipRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetGCClipRegion +// setGCClipRegionRequest writes a SetGCClipRegion request to a byte slice. +func setGCClipRegionRequest(c *xgb.Conn, Gc xproto.Gcontext, Region Region, XOrigin int16, YOrigin int16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOrigin)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOrigin)) + b += 2 + + return buf +} + +// SetPictureClipRegionCookie is a cookie used only for SetPictureClipRegion requests. +type SetPictureClipRegionCookie struct { + *xgb.Cookie +} + +// SetPictureClipRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPictureClipRegion(c *xgb.Conn, Picture render.Picture, Region Region, XOrigin int16, YOrigin int16) SetPictureClipRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetPictureClipRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPictureClipRegionRequest(c, Picture, Region, XOrigin, YOrigin), cookie) + return SetPictureClipRegionCookie{cookie} +} + +// SetPictureClipRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPictureClipRegionCookie.Check() +func SetPictureClipRegionChecked(c *xgb.Conn, Picture render.Picture, Region Region, XOrigin int16, YOrigin int16) SetPictureClipRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetPictureClipRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPictureClipRegionRequest(c, Picture, Region, XOrigin, YOrigin), cookie) + return SetPictureClipRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPictureClipRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPictureClipRegion +// setPictureClipRegionRequest writes a SetPictureClipRegion request to a byte slice. +func setPictureClipRegionRequest(c *xgb.Conn, Picture render.Picture, Region Region, XOrigin int16, YOrigin int16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 22 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Picture)) + b += 4 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put16(buf[b:], uint16(XOrigin)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOrigin)) + b += 2 + + return buf +} + +// SetRegionCookie is a cookie used only for SetRegion requests. +type SetRegionCookie struct { + *xgb.Cookie +} + +// SetRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetRegion(c *xgb.Conn, Region Region, Rectangles []xproto.Rectangle) SetRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setRegionRequest(c, Region, Rectangles), cookie) + return SetRegionCookie{cookie} +} + +// SetRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using SetRegionCookie.Check() +func SetRegionChecked(c *xgb.Conn, Region Region, Rectangles []xproto.Rectangle) SetRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setRegionRequest(c, Region, Rectangles), cookie) + return SetRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetRegion +// setRegionRequest writes a SetRegion request to a byte slice. +func setRegionRequest(c *xgb.Conn, Region Region, Rectangles []xproto.Rectangle) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + b += xproto.RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// SetWindowShapeRegionCookie is a cookie used only for SetWindowShapeRegion requests. +type SetWindowShapeRegionCookie struct { + *xgb.Cookie +} + +// SetWindowShapeRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetWindowShapeRegion(c *xgb.Conn, Dest xproto.Window, DestKind shape.Kind, XOffset int16, YOffset int16, Region Region) SetWindowShapeRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetWindowShapeRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setWindowShapeRegionRequest(c, Dest, DestKind, XOffset, YOffset, Region), cookie) + return SetWindowShapeRegionCookie{cookie} +} + +// SetWindowShapeRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using SetWindowShapeRegionCookie.Check() +func SetWindowShapeRegionChecked(c *xgb.Conn, Dest xproto.Window, DestKind shape.Kind, XOffset int16, YOffset int16, Region Region) SetWindowShapeRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetWindowShapeRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setWindowShapeRegionRequest(c, Dest, DestKind, XOffset, YOffset, Region), cookie) + return SetWindowShapeRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetWindowShapeRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetWindowShapeRegion +// setWindowShapeRegionRequest writes a SetWindowShapeRegion request to a byte slice. +func setWindowShapeRegionRequest(c *xgb.Conn, Dest xproto.Window, DestKind shape.Kind, XOffset int16, YOffset int16, Region Region) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 21 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Dest)) + b += 4 + + buf[b] = byte(DestKind) + b += 1 + + b += 3 // padding + + xgb.Put16(buf[b:], uint16(XOffset)) + b += 2 + + xgb.Put16(buf[b:], uint16(YOffset)) + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + return buf +} + +// ShowCursorCookie is a cookie used only for ShowCursor requests. +type ShowCursorCookie struct { + *xgb.Cookie +} + +// ShowCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ShowCursor(c *xgb.Conn, Window xproto.Window) ShowCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ShowCursor' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(showCursorRequest(c, Window), cookie) + return ShowCursorCookie{cookie} +} + +// ShowCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using ShowCursorCookie.Check() +func ShowCursorChecked(c *xgb.Conn, Window xproto.Window) ShowCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'ShowCursor' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(showCursorRequest(c, Window), cookie) + return ShowCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ShowCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ShowCursor +// showCursorRequest writes a ShowCursor request to a byte slice. +func showCursorRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 30 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// SubtractRegionCookie is a cookie used only for SubtractRegion requests. +type SubtractRegionCookie struct { + *xgb.Cookie +} + +// SubtractRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SubtractRegion(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) SubtractRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SubtractRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(subtractRegionRequest(c, Source1, Source2, Destination), cookie) + return SubtractRegionCookie{cookie} +} + +// SubtractRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using SubtractRegionCookie.Check() +func SubtractRegionChecked(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) SubtractRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SubtractRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(subtractRegionRequest(c, Source1, Source2, Destination), cookie) + return SubtractRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SubtractRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SubtractRegion +// subtractRegionRequest writes a SubtractRegion request to a byte slice. +func subtractRegionRequest(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source1)) + b += 4 + + xgb.Put32(buf[b:], uint32(Source2)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} + +// TranslateRegionCookie is a cookie used only for TranslateRegion requests. +type TranslateRegionCookie struct { + *xgb.Cookie +} + +// TranslateRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func TranslateRegion(c *xgb.Conn, Region Region, Dx int16, Dy int16) TranslateRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'TranslateRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(translateRegionRequest(c, Region, Dx, Dy), cookie) + return TranslateRegionCookie{cookie} +} + +// TranslateRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using TranslateRegionCookie.Check() +func TranslateRegionChecked(c *xgb.Conn, Region Region, Dx int16, Dy int16) TranslateRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'TranslateRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(translateRegionRequest(c, Region, Dx, Dy), cookie) + return TranslateRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook TranslateRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for TranslateRegion +// translateRegionRequest writes a TranslateRegion request to a byte slice. +func translateRegionRequest(c *xgb.Conn, Region Region, Dx int16, Dy int16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Region)) + b += 4 + + xgb.Put16(buf[b:], uint16(Dx)) + b += 2 + + xgb.Put16(buf[b:], uint16(Dy)) + b += 2 + + return buf +} + +// UnionRegionCookie is a cookie used only for UnionRegion requests. +type UnionRegionCookie struct { + *xgb.Cookie +} + +// UnionRegion sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnionRegion(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) UnionRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'UnionRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(unionRegionRequest(c, Source1, Source2, Destination), cookie) + return UnionRegionCookie{cookie} +} + +// UnionRegionChecked sends a checked request. +// If an error occurs, it can be retrieved using UnionRegionCookie.Check() +func UnionRegionChecked(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) UnionRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'UnionRegion' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(unionRegionRequest(c, Source1, Source2, Destination), cookie) + return UnionRegionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnionRegionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnionRegion +// unionRegionRequest writes a UnionRegion request to a byte slice. +func unionRegionRequest(c *xgb.Conn, Source1 Region, Source2 Region, Destination Region) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Source1)) + b += 4 + + xgb.Put32(buf[b:], uint32(Source2)) + b += 4 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + return buf +} diff --git a/vend/xgb/xgb.go b/vend/xgb/xgb.go new file mode 100644 index 0000000..d605da6 --- /dev/null +++ b/vend/xgb/xgb.go @@ -0,0 +1,608 @@ +package xgb + +import ( + "errors" + "io" + "log" + "net" + "os" + "sync" +) + +var ( + // Where to log error-messages. Defaults to stderr. + // To disable logging, just set this to log.New(ioutil.Discard, "", 0) + Logger = log.New(os.Stderr, "XGB: ", log.Lshortfile) +) + +const ( + // cookieBuffer represents the queue size of cookies existing at any + // point in time. The size of the buffer is really only important when + // there are many requests without replies made in sequence. Once the + // buffer fills, a round trip request is made to clear the buffer. + cookieBuffer = 1000 + + // xidBuffer represents the queue size of the xid channel. + // I don't think this value matters much, since xid generation is not + // that expensive. + xidBuffer = 5 + + // seqBuffer represents the queue size of the sequence number channel. + // I don't think this value matters much, since sequence number generation + // is not that expensive. + seqBuffer = 5 + + // reqBuffer represents the queue size of the number of requests that + // can be made until new ones block. This value seems OK. + reqBuffer = 100 + + // eventBuffer represents the queue size of the number of events or errors + // that can be loaded off the wire and not grabbed with WaitForEvent + // until reading an event blocks. This value should be big enough to handle + // bursts of events. + eventBuffer = 5000 +) + +// A Conn represents a connection to an X server. +type Conn struct { + host string + conn net.Conn + display string + DisplayNumber int + DefaultScreen int + SetupBytes []byte + + setupResourceIdBase uint32 + setupResourceIdMask uint32 + + eventChan chan eventOrError + cookieChan chan *Cookie + xidChan chan xid + seqChan chan uint16 + reqChan chan *request + doneSend chan struct{} + doneRead chan struct{} + + // ExtLock is a lock used whenever new extensions are initialized. + // It should not be used. It is exported for use in the extension + // sub-packages. + ExtLock sync.RWMutex + + // Extensions is a map from extension name to major opcode. It should + // not be used. It is exported for use in the extension sub-packages. + Extensions map[string]byte +} + +// NewConn creates a new connection instance. It initializes locks, data +// structures, and performs the initial handshake. (The code for the handshake +// has been relegated to conn.go.) +// It is up to user to close connection with Close() method to finish all unfinished requests and clean up spawned goroutines. +// If the connection unexpectedly closes itself and WaitForEvent() returns "nil, nil", everything is cleaned by that moment, but nothing bad happens if you call Close() after. +func NewConn() (*Conn, error) { + return NewConnDisplay("") +} + +// NewConnDisplay is just like NewConn (see closing instructions), but allows a specific DISPLAY +// string to be used. +// If 'display' is empty it will be taken from os.Getenv("DISPLAY"). +// +// Examples: +// NewConn(":1") -> net.Dial("unix", "", "/tmp/.X11-unix/X1") +// NewConn("/tmp/launch-12/:0") -> net.Dial("unix", "", "/tmp/launch-12/:0") +// NewConn("hostname:2.1") -> net.Dial("tcp", "", "hostname:6002") +// NewConn("tcp/hostname:1.0") -> net.Dial("tcp", "", "hostname:6001") +func NewConnDisplay(display string) (*Conn, error) { + c := &Conn{} + + // First connect. This reads authority, checks DISPLAY environment + // variable, and loads the initial Setup info. + err := c.connect(display) + if err != nil { + return nil, err + } + + return postNewConn(c) +} + +// NewConnNet is just like NewConn (see closing instructions), but allows a specific net.Conn +// to be used. +func NewConnNet(netConn net.Conn) (*Conn, error) { + c := &Conn{} + + // First connect. This reads authority, checks DISPLAY environment + // variable, and loads the initial Setup info. + err := c.connectNet(netConn) + + if err != nil { + return nil, err + } + + return postNewConn(c) +} + +func postNewConn(c *Conn) (*Conn, error) { + c.Extensions = make(map[string]byte) + + c.cookieChan = make(chan *Cookie, cookieBuffer) + c.xidChan = make(chan xid, xidBuffer) + c.seqChan = make(chan uint16, seqBuffer) + c.reqChan = make(chan *request, reqBuffer) + c.eventChan = make(chan eventOrError, eventBuffer) + c.doneSend = make(chan struct{}) + c.doneRead = make(chan struct{}) + + go c.generateXIds() + go c.generateSeqIds() + go c.sendRequests() + go c.readResponses() + + return c, nil +} + +// Close gracefully closes the connection to the X server. +// When everything is cleaned up, the WaitForEvent method will return (nil, nil) +func (c *Conn) Close() { + select { + case c.reqChan <- nil: + case <-c.doneSend: + } +} + +// Event is an interface that can contain any of the events returned by the +// server. Use a type assertion switch to extract the Event structs. +type Event interface { + Bytes() []byte + String() string +} + +// NewEventFun is the type of function use to construct events from raw bytes. +// It should not be used. It is exported for use in the extension sub-packages. +type NewEventFun func(buf []byte) Event + +// NewEventFuncs is a map from event numbers to functions that create +// the corresponding event. It should not be used. It is exported for use +// in the extension sub-packages. +var NewEventFuncs = make(map[int]NewEventFun) + +// NewExtEventFuncs is a temporary map that stores event constructor functions +// for each extension. When an extension is initialized, each event for that +// extension is added to the 'NewEventFuncs' map. It should not be used. It is +// exported for use in the extension sub-packages. +var NewExtEventFuncs = make(map[string]map[int]NewEventFun) + +// Error is an interface that can contain any of the errors returned by +// the server. Use a type assertion switch to extract the Error structs. +type Error interface { + SequenceId() uint16 + BadId() uint32 + Error() string +} + +// NewErrorFun is the type of function use to construct errors from raw bytes. +// It should not be used. It is exported for use in the extension sub-packages. +type NewErrorFun func(buf []byte) Error + +// NewErrorFuncs is a map from error numbers to functions that create +// the corresponding error. It should not be used. It is exported for use in +// the extension sub-packages. +var NewErrorFuncs = make(map[int]NewErrorFun) + +// NewExtErrorFuncs is a temporary map that stores error constructor functions +// for each extension. When an extension is initialized, each error for that +// extension is added to the 'NewErrorFuncs' map. It should not be used. It is +// exported for use in the extension sub-packages. +var NewExtErrorFuncs = make(map[string]map[int]NewErrorFun) + +// eventOrError corresponds to values that can be either an event or an +// error. +type eventOrError interface{} + +// NewId generates a new unused ID for use with requests like CreateWindow. +// If no new ids can be generated, the id returned is 0 and error is non-nil. +// This shouldn't be used directly, and is exported for use in the extension +// sub-packages. +// If you need identifiers, use the appropriate constructor. +// e.g., For a window id, use xproto.NewWindowId. For +// a new pixmap id, use xproto.NewPixmapId. And so on. +// Returns (0, io.EOF) when the connection is closed. +func (c *Conn) NewId() (uint32, error) { + xid, ok := <-c.xidChan + if !ok { + return 0, io.EOF + } + if xid.err != nil { + return 0, xid.err + } + return xid.id, nil +} + +// xid encapsulates a resource identifier being sent over the Conn.xidChan +// channel. If no new resource id can be generated, id is set to 0 and a +// non-nil error is set in xid.err. +type xid struct { + id uint32 + err error +} + +// generateXids sends new Ids down the channel for NewId to use. +// generateXids should be run in its own goroutine. +// This needs to be updated to use the XC Misc extension once we run out of +// new ids. +// Thanks to libxcb/src/xcb_xid.c. This code is greatly inspired by it. +func (c *Conn) generateXIds() { + defer close(c.xidChan) + + // This requires some explanation. From the horse's mouth: + // "The resource-id-mask contains a single contiguous set of bits (at least + // 18). The client allocates resource IDs for types WINDOW, PIXMAP, + // CURSOR, FONT, GCONTEXT, and COLORMAP by choosing a value with only some + // subset of these bits set and ORing it with resource-id-base. Only values + // constructed in this way can be used to name newly created resources over + // this connection." + // So for example (using 8 bit integers), the mask might look like: + // 00111000 + // So that valid values would be 00101000, 00110000, 00001000, and so on. + // Thus, the idea is to increment it by the place of the last least + // significant '1'. In this case, that value would be 00001000. To get + // that value, we can AND the original mask with its two's complement: + // 00111000 & 11001000 = 00001000. + // And we use that value to increment the last resource id to get a new one. + // (And then, of course, we OR it with resource-id-base.) + inc := c.setupResourceIdMask & -c.setupResourceIdMask + max := c.setupResourceIdMask + last := uint32(0) + for { + id := xid{} + if last > 0 && last >= max-inc+1 { + // TODO: Use the XC Misc extension to look for released ids. + id = xid{ + id: 0, + err: errors.New("There are no more available resource identifiers."), + } + } else { + last += inc + id = xid{ + id: last | c.setupResourceIdBase, + err: nil, + } + } + + select { + case c.xidChan <- id: + case <-c.doneSend: + // c.sendRequests is down and since this id is used by requests, we don't need this goroutine running anymore. + return + } + } +} + +// newSeqId fetches the next sequence id from the Conn.seqChan channel. +func (c *Conn) newSequenceId() uint16 { + return <-c.seqChan +} + +// generateSeqIds returns new sequence ids. It is meant to be run in its +// own goroutine. +// A sequence id is generated for *every* request. It's the identifier used +// to match up replies with requests. +// Since sequence ids can only be 16 bit integers we start over at zero when it +// comes time to wrap. +// N.B. As long as the cookie buffer is less than 2^16, there are no limitations +// on the number (or kind) of requests made in sequence. +func (c *Conn) generateSeqIds() { + defer close(c.seqChan) + + seqid := uint16(1) + for { + select { + case c.seqChan <- seqid: + if seqid == uint16((1<<16)-1) { + seqid = 0 + } else { + seqid++ + } + case <-c.doneSend: + // c.sendRequests is down and since only that function uses sequence ids (via newSequenceId method), we don't need this goroutine running anymore. + return + } + } +} + +// request encapsulates a buffer of raw bytes (containing the request data) +// and a cookie, which when combined represents a single request. +// The cookie is used to match up the reply/error. +type request struct { + buf []byte + cookie *Cookie + + // seq is closed when the request (cookie) has been sequenced by the Conn. + seq chan struct{} +} + +// NewRequest takes the bytes and a cookie of a particular request, constructs +// a request type, and sends it over the Conn.reqChan channel. +// Note that the sequence number is added to the cookie after it is sent +// over the request channel, but before it is sent to X. +// +// Note that you may safely use NewRequest to send arbitrary byte requests +// to X. The resulting cookie can be used just like any normal cookie and +// abides by the same rules, except that for replies, you'll get back the +// raw byte data. This may be useful for performance critical sections where +// every allocation counts, since all X requests in XGB allocate a new byte +// slice. In contrast, NewRequest allocates one small request struct and +// nothing else. (Except when the cookie buffer is full and has to be flushed.) +// +// If you're using NewRequest manually, you'll need to use NewCookie to create +// a new cookie. +// +// In all likelihood, you should be able to copy and paste with some minor +// edits the generated code for the request you want to issue. +func (c *Conn) NewRequest(buf []byte, cookie *Cookie) { + seq := make(chan struct{}) + select { + case c.reqChan <- &request{buf: buf, cookie: cookie, seq: seq}: + // request is in buffer + // wait until request is processed or connection is closed + select { + case <-seq: + // request was successfully sent to X server + case <-c.doneSend: + // c.sendRequests is down, your request was not handled + } + case <-c.doneSend: + // c.sendRequests is down, nobody is listening to your requests + } +} + +// sendRequests is run as a single goroutine that takes requests and writes +// the bytes to the wire and adds the cookie to the cookie queue. +// It is meant to be run as its own goroutine. +func (c *Conn) sendRequests() { + defer close(c.cookieChan) + defer c.conn.Close() + defer close(c.doneSend) + + for { + select { + case req := <-c.reqChan: + if req == nil { + // a request by c.Close() to gracefully exit + // Flush the response reading goroutine. + if err := c.noop(); err != nil { + c.conn.Close() + <-c.doneRead + } + return + } + // ho there! if the cookie channel is nearly full, force a round + // trip to clear out the cookie buffer. + // Note that we circumvent the request channel, because we're *in* + // the request channel. + if len(c.cookieChan) == cookieBuffer-1 { + if err := c.noop(); err != nil { + // Shut everything down. + c.conn.Close() + <-c.doneRead + return + } + } + req.cookie.Sequence = c.newSequenceId() + c.cookieChan <- req.cookie + if err := c.writeBuffer(req.buf); err != nil { + c.conn.Close() + <-c.doneRead + return + } + close(req.seq) + case <-c.doneRead: + return + } + } +} + +// noop circumvents the usual request sending goroutines and forces a round +// trip request manually. +func (c *Conn) noop() error { + cookie := c.NewCookie(true, true) + cookie.Sequence = c.newSequenceId() + c.cookieChan <- cookie + if err := c.writeBuffer(c.getInputFocusRequest()); err != nil { + return err + } + cookie.Reply() // wait for the buffer to clear + return nil +} + +// writeBuffer is a convenience function for writing a byte slice to the wire. +func (c *Conn) writeBuffer(buf []byte) error { + if _, err := c.conn.Write(buf); err != nil { + Logger.Printf("A write error is unrecoverable: %s", err) + return err + } + return nil +} + +// readResponses is a goroutine that reads events, errors and +// replies off the wire. +// When an event is read, it is always added to the event channel. +// When an error is read, if it corresponds to an existing checked cookie, +// it is sent to that cookie's error channel. Otherwise it is added to the +// event channel. +// When a reply is read, it is added to the corresponding cookie's reply +// channel. (It is an error if no such cookie exists in this case.) +// Finally, cookies that came "before" this reply are always cleaned up. +func (c *Conn) readResponses() { + defer close(c.eventChan) + defer c.conn.Close() + defer close(c.doneRead) + + var ( + err Error + seq uint16 + replyBytes []byte + ) + + for { + buf := make([]byte, 32) + err, seq = nil, 0 + if _, err := io.ReadFull(c.conn, buf); err != nil { + select { + case <-c.doneSend: + // gracefully closing + return + default: + } + Logger.Printf("A read error is unrecoverable: %s", err) + c.eventChan <- err + return + } + switch buf[0] { + case 0: // This is an error + // Use the constructor function for this error (that is auto + // generated) by looking it up by the error number. + newErrFun, ok := NewErrorFuncs[int(buf[1])] + if !ok { + Logger.Printf("BUG: Could not find error constructor function "+ + "for error with number %d.", buf[1]) + continue + } + err = newErrFun(buf) + seq = err.SequenceId() + + // This error is either sent to the event channel or a specific + // cookie's error channel below. + case 1: // This is a reply + seq = Get16(buf[2:]) + + // check to see if this reply has more bytes to be read + size := Get32(buf[4:]) + if size > 0 { + byteCount := 32 + size*4 + biggerBuf := make([]byte, byteCount) + copy(biggerBuf[:32], buf) + if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil { + Logger.Printf("A read error is unrecoverable: %s", err) + c.eventChan <- err + return + } + replyBytes = biggerBuf + } else { + replyBytes = buf + } + + // This reply is sent to its corresponding cookie below. + default: // This is an event + // Use the constructor function for this event (like for errors, + // and is also auto generated) by looking it up by the event number. + // Note that we AND the event number with 127 so that we ignore + // the most significant bit (which is set when it was sent from + // a SendEvent request). + evNum := int(buf[0] & 127) + newEventFun, ok := NewEventFuncs[evNum] + if !ok { + Logger.Printf("BUG: Could not find event construct function "+ + "for event with number %d.", evNum) + continue + } + c.eventChan <- newEventFun(buf) + continue + } + + // At this point, we have a sequence number and we're either + // processing an error or a reply, which are both responses to + // requests. So all we have to do is find the cookie corresponding + // to this error/reply, and send the appropriate data to it. + // In doing so, we make sure that any cookies that came before it + // are marked as successful if they are void and checked. + // If there's a cookie that requires a reply that is before this + // reply, then something is wrong. + for cookie := range c.cookieChan { + // This is the cookie we're looking for. Process and break. + if cookie.Sequence == seq { + if err != nil { // this is an error to a request + // synchronous processing + if cookie.errorChan != nil { + cookie.errorChan <- err + } else { // asynchronous processing + c.eventChan <- err + // if this is an unchecked reply, ping the cookie too + if cookie.pingChan != nil { + cookie.pingChan <- true + } + } + } else { // this is a reply + if cookie.replyChan == nil { + Logger.Printf("Reply with sequence id %d does not "+ + "have a cookie with a valid reply channel.", seq) + continue + } else { + cookie.replyChan <- replyBytes + } + } + break + } + + switch { + // Checked requests with replies + case cookie.replyChan != nil && cookie.errorChan != nil: + Logger.Printf("Found cookie with sequence id %d that is "+ + "expecting a reply but will never get it. Currently "+ + "on sequence number %d", cookie.Sequence, seq) + // Unchecked requests with replies + case cookie.replyChan != nil && cookie.pingChan != nil: + Logger.Printf("Found cookie with sequence id %d that is "+ + "expecting a reply (and not an error) but will never "+ + "get it. Currently on sequence number %d", + cookie.Sequence, seq) + // Checked requests without replies + case cookie.pingChan != nil && cookie.errorChan != nil: + cookie.pingChan <- true + // Unchecked requests without replies don't have any channels, + // so we can't do anything with them except let them pass by. + } + } + } +} + +// processEventOrError takes an eventOrError, type switches on it, +// and returns it in Go idiomatic style. +func processEventOrError(everr eventOrError) (Event, Error) { + switch ee := everr.(type) { + case Event: + return ee, nil + case Error: + return nil, ee + case error: + // c.conn read error + case nil: + // c.eventChan is closed + default: + Logger.Printf("Invalid event/error type: %T", everr) + } + return nil, nil +} + +// WaitForEvent returns the next event from the server. +// It will block until an event is available. +// WaitForEvent returns either an Event or an Error. (Returning both +// is a bug.) Note than an Error here is an X error and not an XGB error. That +// is, X errors are sometimes completely expected (and you may want to ignore +// them in some cases). +// +// If both the event and error are nil, then the connection has been closed. +func (c *Conn) WaitForEvent() (Event, Error) { + return processEventOrError(<-c.eventChan) +} + +// PollForEvent returns the next event from the server if one is available in +// the internal queue without blocking. Note that unlike WaitForEvent, both +// Event and Error could be nil. Indeed, they are both nil when the event queue +// is empty. +func (c *Conn) PollForEvent() (Event, Error) { + select { + case everr := <-c.eventChan: + return processEventOrError(everr) + default: + return nil, nil + } +} diff --git a/vend/xgb/xgb_test.go b/vend/xgb/xgb_test.go new file mode 100644 index 0000000..19ed307 --- /dev/null +++ b/vend/xgb/xgb_test.go @@ -0,0 +1,225 @@ +package xgb + +import ( + "errors" + "fmt" + "testing" + "time" +) + +func TestConnOnNonBlockingDummyXServer(t *testing.T) { + timeout := 10 * time.Millisecond + checkedReply := func(wantError bool) func(*Conn) error { + request := "reply" + if wantError { + request = "error" + } + return func(c *Conn) error { + cookie := c.NewCookie(true, true) + c.NewRequest([]byte(request), cookie) + _, err := cookie.Reply() + if wantError && err == nil { + return errors.New(fmt.Sprintf("checked request \"%v\" with reply resulted in nil error, want some error", request)) + } + if !wantError && err != nil { + return errors.New(fmt.Sprintf("checked request \"%v\" with reply resulted in error %v, want nil error", request, err)) + } + return nil + } + } + checkedNoreply := func(wantError bool) func(*Conn) error { + request := "noreply" + if wantError { + request = "error" + } + return func(c *Conn) error { + cookie := c.NewCookie(true, false) + c.NewRequest([]byte(request), cookie) + err := cookie.Check() + if wantError && err == nil { + return errors.New(fmt.Sprintf("checked request \"%v\" with no reply resulted in nil error, want some error", request)) + } + if !wantError && err != nil { + return errors.New(fmt.Sprintf("checked request \"%v\" with no reply resulted in error %v, want nil error", request, err)) + } + return nil + } + } + uncheckedReply := func(wantError bool) func(*Conn) error { + request := "reply" + if wantError { + request = "error" + } + return func(c *Conn) error { + cookie := c.NewCookie(false, true) + c.NewRequest([]byte(request), cookie) + _, err := cookie.Reply() + if err != nil { + return errors.New(fmt.Sprintf("unchecked request \"%v\" with reply resulted in %v, want nil", request, err)) + } + return nil + } + } + uncheckedNoreply := func(wantError bool) func(*Conn) error { + request := "noreply" + if wantError { + request = "error" + } + return func(c *Conn) error { + cookie := c.NewCookie(false, false) + c.NewRequest([]byte(request), cookie) + return nil + } + } + event := func() func(*Conn) error { + return func(c *Conn) error { + _, err := c.conn.Write([]byte("event")) + if err != nil { + return errors.New(fmt.Sprintf("asked dummy server to send event, but resulted in error: %v\n", err)) + } + return err + } + } + waitEvent := func(wantError bool) func(*Conn) error { + return func(c *Conn) error { + _, err := c.WaitForEvent() + if wantError && err == nil { + return errors.New(fmt.Sprintf("wait for event resulted in nil error, want some error")) + } + if !wantError && err != nil { + return errors.New(fmt.Sprintf("wait for event resulted in error %v, want nil error", err)) + } + return nil + } + } + checkClosed := func(c *Conn) error { + select { + case eoe, ok := <-c.eventChan: + if ok { + return fmt.Errorf("(*Conn).eventChan should be closed, but is not and returns %v", eoe) + } + case <-time.After(timeout): + return fmt.Errorf("(*Conn).eventChan should be closed, but is not and was blocking for %v", timeout) + } + return nil + } + + testCases := []struct { + description string + actions []func(*Conn) error + }{ + {"close", + []func(*Conn) error{}, + }, + {"double close", + []func(*Conn) error{ + func(c *Conn) error { + c.Close() + return nil + }, + }, + }, + {"checked requests with reply", + []func(*Conn) error{ + checkedReply(false), + checkedReply(true), + checkedReply(false), + checkedReply(true), + }, + }, + {"checked requests no reply", + []func(*Conn) error{ + checkedNoreply(false), + checkedNoreply(true), + checkedNoreply(false), + checkedNoreply(true), + }, + }, + {"unchecked requests with reply", + []func(*Conn) error{ + uncheckedReply(false), + uncheckedReply(true), + waitEvent(true), + uncheckedReply(false), + event(), + waitEvent(false), + }, + }, + {"unchecked requests no reply", + []func(*Conn) error{ + uncheckedNoreply(false), + uncheckedNoreply(true), + waitEvent(true), + uncheckedNoreply(false), + event(), + waitEvent(false), + }, + }, + {"close with pending requests", + []func(*Conn) error{ + func(c *Conn) error { + c.conn.(*dNC).ReadLock() + defer c.conn.(*dNC).ReadUnlock() + c.NewRequest([]byte("reply"), c.NewCookie(false, true)) + c.Close() + return nil + }, + checkClosed, + }, + }, + {"unexpected conn close", + []func(*Conn) error{ + func(c *Conn) error { + c.conn.Close() + if ev, err := c.WaitForEvent(); ev != nil || err != nil { + return fmt.Errorf("WaitForEvent() = (%v, %v), want (nil, nil)", ev, err) + } + return nil + }, + checkClosed, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + sclm := leaksMonitor("after server close, before testcase exit") + defer sclm.checkTesting(t) + + s := newDummyNetConn("dummyX", newDummyXServerReplier()) + defer s.Close() + + c, err := postNewConn(&Conn{conn: s}) + if err != nil { + t.Errorf("connect to dummy server error: %v", err) + return + } + + defer leaksMonitor("after actions end", sclm).checkTesting(t) + + for _, action := range tc.actions { + if err := action(c); err != nil { + t.Error(err) + break + } + } + + recovered := false + func() { + defer func() { + if err := recover(); err != nil { + t.Errorf("(*Conn).Close() panic recover: %v", err) + recovered = true + } + }() + + c.Close() + }() + if !recovered { + if err := checkClosed(c); err != nil { + t.Error(err) + } + } + + }) + } +} diff --git a/vend/xgb/xgbgen/COPYING b/vend/xgb/xgbgen/COPYING new file mode 100644 index 0000000..5c93f45 --- /dev/null +++ b/vend/xgb/xgbgen/COPYING @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/vend/xgb/xgbgen/context.go b/vend/xgb/xgbgen/context.go new file mode 100644 index 0000000..2e31598 --- /dev/null +++ b/vend/xgb/xgbgen/context.go @@ -0,0 +1,168 @@ +package main + +import ( + "bytes" + "encoding/xml" + "fmt" + "log" + "sort" +) + +// Context represents the protocol we're converting to Go, and a writer +// buffer to write the Go source to. +type Context struct { + protocol *Protocol + out *bytes.Buffer +} + +func newContext() *Context { + return &Context{ + out: bytes.NewBuffer([]byte{}), + } +} + +// Putln calls put and adds a new line to the end of 'format'. +func (c *Context) Putln(format string, v ...interface{}) { + c.Put(format+"\n", v...) +} + +// Put is a short alias to write to 'out'. +func (c *Context) Put(format string, v ...interface{}) { + _, err := c.out.WriteString(fmt.Sprintf(format, v...)) + if err != nil { + log.Fatalf("There was an error writing to context buffer: %s", err) + } +} + +// Morph is the big daddy of them all. It takes in an XML byte slice, +// parse it, transforms the XML types into more usable types, +// and writes Go code to the 'out' buffer. +func (c *Context) Morph(xmlBytes []byte) { + parsedXml := &XML{} + err := xml.Unmarshal(xmlBytes, parsedXml) + if err != nil { + log.Fatal(err) + } + + // Parse all imports + parsedXml.Imports.Eval() + + // Translate XML types to nice types + c.protocol = parsedXml.Translate(nil) + + // For backwards compatibility we patch the type of the send_event field of + // PutImage to be byte + if c.protocol.Name == "shm" { + for _, req := range c.protocol.Requests { + if req.xmlName != "PutImage" { + continue + } + for _, ifield := range req.Fields { + field, ok := ifield.(*SingleField) + if !ok || field.xmlName != "send_event" { + continue + } + field.Type = &Base{ srcName: "byte", xmlName: "CARD8", size: newFixedSize(1, true) } + } + } + } + + // Start with Go header. + c.Putln("// Package %s is the X client API for the %s extension.", + c.protocol.PkgName(), c.protocol.ExtXName) + c.Putln("package %s", c.protocol.PkgName()) + c.Putln("") + c.Putln("// This file is automatically generated from %s.xml. "+ + "Edit at your peril!", c.protocol.Name) + c.Putln("") + + // Write imports. We always need to import at least xgb. + // We also need to import xproto if it's an extension. + c.Putln("import (") + c.Putln("\"github.com/jezek/xgb\"") + c.Putln("") + if c.protocol.isExt() { + c.Putln("\"github.com/jezek/xgb/xproto\"") + } + + sort.Sort(Protocols(c.protocol.Imports)) + for _, imp := range c.protocol.Imports { + // We always import xproto, so skip it if it's explicitly imported + if imp.Name == "xproto" { + continue + } + c.Putln("\"github.com/jezek/xgb/%s\"", imp.Name) + } + c.Putln(")") + c.Putln("") + + // If this is an extension, create a function to initialize the extension + // before it can be used. + if c.protocol.isExt() { + xname := c.protocol.ExtXName + + c.Putln("// Init must be called before using the %s extension.", + xname) + c.Putln("func Init(c *xgb.Conn) error {") + c.Putln("reply, err := xproto.QueryExtension(c, %d, \"%s\").Reply()", + len(xname), xname) + c.Putln("switch {") + c.Putln("case err != nil:") + c.Putln("return err") + c.Putln("case !reply.Present:") + c.Putln("return xgb.Errorf(\"No extension named %s could be found on "+ + "on the server.\")", xname) + c.Putln("}") + c.Putln("") + c.Putln("c.ExtLock.Lock()") + c.Putln("c.Extensions[\"%s\"] = reply.MajorOpcode", xname) + c.Putln("c.ExtLock.Unlock()") + c.Putln("for evNum, fun := range xgb.NewExtEventFuncs[\"%s\"] {", + xname) + c.Putln("xgb.NewEventFuncs[int(reply.FirstEvent) + evNum] = fun") + c.Putln("}") + c.Putln("for errNum, fun := range xgb.NewExtErrorFuncs[\"%s\"] {", + xname) + c.Putln("xgb.NewErrorFuncs[int(reply.FirstError) + errNum] = fun") + c.Putln("}") + c.Putln("return nil") + c.Putln("}") + c.Putln("") + + // Make sure newExtEventFuncs["EXT_NAME"] map is initialized. + // Same deal for newExtErrorFuncs["EXT_NAME"] + c.Putln("func init() {") + c.Putln("xgb.NewExtEventFuncs[\"%s\"] = make(map[int]xgb.NewEventFun)", + xname) + c.Putln("xgb.NewExtErrorFuncs[\"%s\"] = make(map[int]xgb.NewErrorFun)", + xname) + c.Putln("}") + c.Putln("") + } else { + // In the xproto package, we must provide a Setup function that uses + // SetupBytes in xgb.Conn to return a SetupInfo structure. + c.Putln("// Setup parses the setup bytes retrieved when") + c.Putln("// connecting into a SetupInfo struct.") + c.Putln("func Setup(c *xgb.Conn) *SetupInfo {") + c.Putln("setup := new(SetupInfo)") + c.Putln("SetupInfoRead(c.SetupBytes, setup)") + c.Putln("return setup") + c.Putln("}") + c.Putln("") + c.Putln("// DefaultScreen gets the default screen info from SetupInfo.") + c.Putln("func (s *SetupInfo) DefaultScreen(c *xgb.Conn) *ScreenInfo {") + c.Putln("return &s.Roots[c.DefaultScreen]") + c.Putln("}") + c.Putln("") + } + + // Now write Go source code + sort.Sort(Types(c.protocol.Types)) + sort.Sort(Requests(c.protocol.Requests)) + for _, typ := range c.protocol.Types { + typ.Define(c) + } + for _, req := range c.protocol.Requests { + req.Define(c) + } +} diff --git a/vend/xgb/xgbgen/doc.go b/vend/xgb/xgbgen/doc.go new file mode 100644 index 0000000..4ba6145 --- /dev/null +++ b/vend/xgb/xgbgen/doc.go @@ -0,0 +1,74 @@ +/* +xgbgen constructs Go source files from xproto XML description files. xgbgen +accomplishes the same task as the Python code generator for XCB and xpyb. + +Usage: + xgbgen [flags] some-protocol.xml + +The flags are: + --proto-path path + The path to a directory containing xproto XML description files. + This is only necessary when 'some-protocol.xml' imports other + protocol files. + --gofmt=true + When false, the outputted Go code will not be gofmt'd. And it won't + be very pretty at all. This is typically useful if there are syntax + errors that need to be debugged in code generation. gofmt will hiccup; + this will allow you to see the raw code. + +How it works + +xgbgen works by parsing the input XML file using Go's encoding/xml package. +The majority of this work is done in xml.go and xml_fields.go, where the +appropriate types are declared. + +Due to the nature of the XML in the protocol description files, the types +required to parse the XML are not well suited to reasoning about code +generation. Because of this, all data parsed in the XML types is translated +into more reasonable types. This translation is done in translation.go, +and is mainly grunt work. (The only interesting tidbits are the translation +of XML names to Go source names, and connecting fields with their +appropriate types.) + +The organization of these types is greatly +inspired by the description of the XML found here: +http://cgit.freedesktop.org/xcb/proto/tree/doc/xml-xcb.txt + +These types come with a lot of supporting methods to make their use in +code generation easier. They can be found in expression.go, field.go, +protocol.go, request_reply.go and type.go. Of particular interest are +expression evaluation and size calculation (in bytes). + +These types also come with supporting methods that convert their +representation into Go source code. I've quartered such methods in +go.go, go_error.go, go_event.go, go_list.go, go_request_reply.go, +go_single_field.go, go_struct.go and go_union.go. The idea is to keep +as much of the Go specific code generation in one area as possible. Namely, +while not *all* Go related code is found in the 'go*.go' files, *most* +of it is. (If there's any interest in using xgbgen for other languages, +I'd be happy to try and make xgbgen a little more friendly in this regard. +I did, however, design xgbgen with this in mind, so it shouldn't involve +anything as serious as a re-design.) + +Why + +I wrote xgbgen because I found the existing code generator that was written in +Python to be unwieldy. In particular, static and strong typing greatly helped +me reason better about the code generation task. + +What does not work + +The core X protocol should be completely working. As far as I know, most +extensions should work too, although I've only tested (and not much) the +Xinerama and RandR extensions. + +XKB does not work. I don't have any real plans of working on this unless there +is demand and I have some test cases to work with. (i.e., even if I could get +something generated for XKB, I don't have the inclination to understand it +enough to verify that it works.) XKB poses several extremely difficult +problems that XCB also has trouble with. More info on that can be found at +http://cgit.freedesktop.org/xcb/libxcb/tree/doc/xkb_issues and +http://cgit.freedesktop.org/xcb/libxcb/tree/doc/xkb_internals. + +*/ +package main diff --git a/vend/xgb/xgbgen/expression.go b/vend/xgb/xgbgen/expression.go new file mode 100644 index 0000000..3e2235d --- /dev/null +++ b/vend/xgb/xgbgen/expression.go @@ -0,0 +1,436 @@ +package main + +import ( + "fmt" + "log" +) + +// Expression represents all the different forms of expressions possible in +// side an XML protocol description file. It's also received a few custom +// addendums to make applying special functions (like padding) easier. +type Expression interface { + // Concrete determines whether this particular expression can be computed + // to some constant value inside xgbgen. (The alternative is that the + // expression can only be computed with values at run time of the + // generated code.) + Concrete() bool + + // Eval evaluates a concrete expression. It is an error to call Eval + // on any expression that is not concrete (or contains any sub-expression + // that is not concrete). + Eval() int + + // Reduce attempts to evaluate any concrete sub-expressions. + // i.e., (1 + 2 * (5 + 1 + someSizeOfStruct) reduces to + // (3 * (6 + someSizeOfStruct)). + // 'prefix' is used preprended to any field reference name. + Reduce(prefix string) string + + // String is an alias for Reduce("") + String() string + + // Initialize makes sure all names in this expression and any subexpressions + // have been translated to Go source names. + Initialize(p *Protocol) + + // Makes all field references relative to path + Specialize(path string) Expression +} + +// Function is a custom expression not found in the XML. It's simply used +// to apply a function named in 'Name' to the Expr expression. +type Function struct { + Name string + Expr Expression +} + +func (e *Function) Concrete() bool { + return false +} + +func (e *Function) Eval() int { + log.Fatalf("Cannot evaluate a 'Function'. It is not concrete.") + panic("unreachable") +} + +func (e *Function) Reduce(prefix string) string { + return fmt.Sprintf("%s(%s)", e.Name, e.Expr.Reduce(prefix)) +} + +func (e *Function) String() string { + return e.Reduce("") +} + +func (e *Function) Initialize(p *Protocol) { + e.Expr.Initialize(p) +} + +func (e *Function) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + +// BinaryOp is an expression that performs some operation (defined in the XML +// file) with Expr1 and Expr2 as operands. +type BinaryOp struct { + Op string + Expr1 Expression + Expr2 Expression +} + +// newBinaryOp constructs a new binary expression when both expr1 and expr2 +// are not nil. If one or both are nil, then the non-nil expression is +// returned unchanged or nil is returned. +func newBinaryOp(op string, expr1, expr2 Expression) Expression { + switch { + case expr1 != nil && expr2 != nil: + return &BinaryOp{ + Op: op, + Expr1: expr1, + Expr2: expr2, + } + case expr1 != nil && expr2 == nil: + return expr1 + case expr1 == nil && expr2 != nil: + return expr2 + case expr1 == nil && expr2 == nil: + return nil + } + panic("unreachable") +} + +func (e *BinaryOp) Concrete() bool { + return e.Expr1.Concrete() && e.Expr2.Concrete() +} + +func (e *BinaryOp) Eval() int { + switch e.Op { + case "+": + return e.Expr1.Eval() + e.Expr2.Eval() + case "-": + return e.Expr1.Eval() - e.Expr2.Eval() + case "*": + return e.Expr1.Eval() * e.Expr2.Eval() + case "/": + return e.Expr1.Eval() / e.Expr2.Eval() + case "&": + return e.Expr1.Eval() & e.Expr2.Eval() + case "<<": + return int(uint(e.Expr1.Eval()) << uint(e.Expr2.Eval())) + } + + log.Fatalf("Invalid binary operator '%s' for expression.", e.Op) + panic("unreachable") +} + +func (e *BinaryOp) Reduce(prefix string) string { + if e.Concrete() { + return fmt.Sprintf("%d", e.Eval()) + } + + // An incredibly dirty hack to make sure any time we perform an operation + // on a field, we're dealing with ints... + expr1, expr2 := e.Expr1, e.Expr2 + switch expr1.(type) { + case *FieldRef: + expr1 = &Function{ + Name: "int", + Expr: expr1, + } + } + switch expr2.(type) { + case *FieldRef: + expr2 = &Function{ + Name: "int", + Expr: expr2, + } + } + return fmt.Sprintf("(%s %s %s)", + expr1.Reduce(prefix), e.Op, expr2.Reduce(prefix)) +} + +func (e *BinaryOp) String() string { + return e.Reduce("") +} + +func (e *BinaryOp) Initialize(p *Protocol) { + e.Expr1.Initialize(p) + e.Expr2.Initialize(p) +} + +func (e *BinaryOp) Specialize(path string) Expression { + r := *e + r.Expr1 = r.Expr1.Specialize(path) + r.Expr2 = r.Expr2.Specialize(path) + return &r +} + +// UnaryOp is the same as BinaryOp, except it's a unary operator with only +// one sub-expression. +type UnaryOp struct { + Op string + Expr Expression +} + +func (e *UnaryOp) Concrete() bool { + return e.Expr.Concrete() +} + +func (e *UnaryOp) Eval() int { + switch e.Op { + case "~": + return ^e.Expr.Eval() + } + + log.Fatalf("Invalid unary operator '%s' for expression.", e.Op) + panic("unreachable") +} + +func (e *UnaryOp) Reduce(prefix string) string { + if e.Concrete() { + return fmt.Sprintf("%d", e.Eval()) + } + return fmt.Sprintf("(%s (%s))", e.Op, e.Expr.Reduce(prefix)) +} + +func (e *UnaryOp) String() string { + return e.Reduce("") +} + +func (e *UnaryOp) Initialize(p *Protocol) { + e.Expr.Initialize(p) +} + +func (e *UnaryOp) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + +// Padding represents the application of the 'pad' function to some +// sub-expression. +type Padding struct { + Expr Expression +} + +func (e *Padding) Concrete() bool { + return e.Expr.Concrete() +} + +func (e *Padding) Eval() int { + return pad(e.Expr.Eval()) +} + +func (e *Padding) Reduce(prefix string) string { + if e.Concrete() { + return fmt.Sprintf("%d", e.Eval()) + } + return fmt.Sprintf("xgb.Pad(%s)", e.Expr.Reduce(prefix)) +} + +func (e *Padding) String() string { + return e.Reduce("") +} + +func (e *Padding) Initialize(p *Protocol) { + e.Expr.Initialize(p) +} + +func (e *Padding) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + +// PopCount represents the application of the 'PopCount' function to +// some sub-expression. +type PopCount struct { + Expr Expression +} + +func (e *PopCount) Concrete() bool { + return e.Expr.Concrete() +} + +func (e *PopCount) Eval() int { + return int(popCount(uint(e.Expr.Eval()))) +} + +func (e *PopCount) Reduce(prefix string) string { + if e.Concrete() { + return fmt.Sprintf("%d", e.Eval()) + } + return fmt.Sprintf("xgb.PopCount(%s)", e.Expr.Reduce(prefix)) +} + +func (e *PopCount) String() string { + return e.Reduce("") +} + +func (e *PopCount) Initialize(p *Protocol) { + e.Expr.Initialize(p) +} + +func (e *PopCount) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + +// Value represents some constant integer. +type Value struct { + v int +} + +func (e *Value) Concrete() bool { + return true +} + +func (e *Value) Eval() int { + return e.v +} + +func (e *Value) Reduce(prefix string) string { + return fmt.Sprintf("%d", e.v) +} + +func (e *Value) String() string { + return e.Reduce("") +} + +func (e *Value) Initialize(p *Protocol) {} + +func (e *Value) Specialize(path string) Expression { + return e +} + +// Bit represents some bit whose value is computed by '1 << bit'. +type Bit struct { + b int +} + +func (e *Bit) Concrete() bool { + return true +} + +func (e *Bit) Eval() int { + return int(1 << uint(e.b)) +} + +func (e *Bit) Reduce(prefix string) string { + return fmt.Sprintf("%d", e.Eval()) +} + +func (e *Bit) String() string { + return e.Reduce("") +} + +func (e *Bit) Initialize(p *Protocol) {} + +func (e *Bit) Specialize(path string) Expression { + return e +} + +// FieldRef represents a reference to some variable in the generated code +// with name Name. +type FieldRef struct { + Name string +} + +func (e *FieldRef) Concrete() bool { + return false +} + +func (e *FieldRef) Eval() int { + log.Fatalf("Cannot evaluate a 'FieldRef'. It is not concrete.") + panic("unreachable") +} + +func (e *FieldRef) Reduce(prefix string) string { + val := e.Name + if len(prefix) > 0 { + val = fmt.Sprintf("%s%s", prefix, val) + } + return val +} + +func (e *FieldRef) String() string { + return e.Reduce("") +} + +func (e *FieldRef) Initialize(p *Protocol) { + e.Name = SrcName(p, e.Name) +} + +func (e *FieldRef) Specialize(path string) Expression { + return &FieldRef{Name: path + "." + e.Name} +} + +// EnumRef represents a reference to some enumeration field. +// EnumKind is the "group" an EnumItem is the name of the specific enumeration +// value inside that group. +type EnumRef struct { + EnumKind Type + EnumItem string +} + +func (e *EnumRef) Concrete() bool { + return false +} + +func (e *EnumRef) Eval() int { + log.Fatalf("Cannot evaluate an 'EnumRef'. It is not concrete.") + panic("unreachable") +} + +func (e *EnumRef) Reduce(prefix string) string { + return fmt.Sprintf("%s%s", e.EnumKind, e.EnumItem) +} + +func (e *EnumRef) String() string { + return e.Reduce("") +} + +func (e *EnumRef) Initialize(p *Protocol) { + e.EnumKind = e.EnumKind.(*Translation).RealType(p) + e.EnumItem = SrcName(p, e.EnumItem) +} + +func (e *EnumRef) Specialize(path string) Expression { + return e +} + +// SumOf represents a summation of the variable in the generated code named by +// Name. It is not currently used. (It's XKB voodoo.) +type SumOf struct { + Name string +} + +func (e *SumOf) Concrete() bool { + return false +} + +func (e *SumOf) Eval() int { + log.Fatalf("Cannot evaluate a 'SumOf'. It is not concrete.") + panic("unreachable") +} + +func (e *SumOf) Reduce(prefix string) string { + if len(prefix) > 0 { + return fmt.Sprintf("sum(%s%s)", prefix, e.Name) + } + return fmt.Sprintf("sum(%s)", e.Name) +} + +func (e *SumOf) String() string { + return e.Reduce("") +} + +func (e *SumOf) Initialize(p *Protocol) { + e.Name = SrcName(p, e.Name) +} + +func (e *SumOf) Specialize(path string) Expression { + return e +} diff --git a/vend/xgb/xgbgen/field.go b/vend/xgb/xgbgen/field.go new file mode 100644 index 0000000..58f54c8 --- /dev/null +++ b/vend/xgb/xgbgen/field.go @@ -0,0 +1,397 @@ +package main + +import ( + "fmt" + "log" + "strings" +) + +// Field corresponds to any field described in an XML protocol description +// file. This includes struct fields, union fields, request fields, +// reply fields and so on. +// To make code generation easier, fields that have types are also stored. +// Note that not all fields support all methods defined in this interface. +// For instance, a padding field does not have a source name. +type Field interface { + // Initialize sets up the source name of this field. + Initialize(p *Protocol) + + // SrcName is the Go source name of this field. + SrcName() string + + // XmlName is the name of this field from the XML file. + XmlName() string + + // SrcType is the Go source type name of this field. + SrcType() string + + // Size returns an expression that computes the size (in bytes) + // of this field. + Size() Size + + // Define writes the Go code to declare this field (in a struct definition). + Define(c *Context) + + // Read writes the Go code to convert a byte slice to a Go value + // of this field. + // 'prefix' is the prefix of the name of the Go value. + Read(c *Context, prefix string) + + // Write writes the Go code to convert a Go value to a byte slice of + // this field. + // 'prefix' is the prefix of the name of the Go value. + Write(c *Context, prefix string) +} + +func (pad *PadField) Initialize(p *Protocol) {} + +// PadField represents any type of padding. It is omitted from +// definitions, but is used in Read/Write to increment the buffer index. +// It is also used in size calculation. +type PadField struct { + Bytes uint + Align uint16 +} + +func (p *PadField) SrcName() string { + panic("illegal to take source name of a pad field") +} + +func (p *PadField) XmlName() string { + panic("illegal to take XML name of a pad field") +} + +func (f *PadField) SrcType() string { + panic("it is illegal to call SrcType on a PadField field") +} + +func (p *PadField) Size() Size { + if p.Align > 0 { + return newFixedSize(uint(p.Align), false) + } else { + return newFixedSize(p.Bytes, true) + } +} + +type RequiredStartAlign struct { +} + +func (f *RequiredStartAlign) Initialize(p *Protocol) { } + +func (f *RequiredStartAlign) SrcName() string { + panic("illegal to take source name of a required_start_align field") +} + +func (f *RequiredStartAlign) XmlName() string { + panic("illegal to take XML name of a required_start_align field") +} + +func (f *RequiredStartAlign) SrcType() string { + panic("it is illegal to call SrcType on a required_start_align field") +} + +func (f *RequiredStartAlign) Size() Size { + return newFixedSize(0, true) +} + +func (f *RequiredStartAlign) Define(c *Context) { } + +func (f *RequiredStartAlign) Read(c *Context, prefix string) { } +func (f *RequiredStartAlign) Write(c *Context, prefix string) { } + +// SingleField represents most of the fields in an XML protocol description. +// It corresponds to any single value. +type SingleField struct { + srcName string + xmlName string + Type Type +} + +func (f *SingleField) Initialize(p *Protocol) { + f.srcName = SrcName(p, f.XmlName()) + f.Type = f.Type.(*Translation).RealType(p) +} + +func (f *SingleField) SrcName() string { + if f.srcName == "Bytes" { + return "Bytes_" + } + return f.srcName +} + +func (f *SingleField) XmlName() string { + return f.xmlName +} + +func (f *SingleField) SrcType() string { + return f.Type.SrcName() +} + +func (f *SingleField) Size() Size { + return f.Type.Size() +} + +// ListField represents a list of values. +type ListField struct { + srcName string + xmlName string + Type Type + LengthExpr Expression +} + +func (f *ListField) SrcName() string { + return f.srcName +} + +func (f *ListField) XmlName() string { + return f.xmlName +} + +func (f *ListField) SrcType() string { + if strings.ToLower(f.Type.XmlName()) == "char" { + return fmt.Sprintf("string") + } + return fmt.Sprintf("[]%s", f.Type.SrcName()) +} + +// Length computes the *number* of values in a list. +// If this ListField does not have any length expression, we throw our hands +// up and simply compute the 'len' of the field name of this list. +func (f *ListField) Length() Size { + if f.LengthExpr == nil { + return newExpressionSize(&Function{ + Name: "len", + Expr: &FieldRef{ + Name: f.SrcName(), + }, + }, true) + } + return newExpressionSize(f.LengthExpr, true) +} + +// Size computes the *size* of a list (in bytes). +// It it typically a simple matter of multiplying the length of the list by +// the size of the type of the list. +// But if it's a list of struct where the struct has a list field, we use a +// special function written in go_struct.go to compute the size (since the +// size in this case can only be computed recursively). +func (f *ListField) Size() Size { + elsz := f.Type.Size() + simpleLen := &Padding{ + Expr: newBinaryOp("*", f.Length().Expression, elsz.Expression), + } + + switch field := f.Type.(type) { + case *Struct: + if field.HasList() { + sizeFun := &Function{ + Name: fmt.Sprintf("%sListSize", f.Type.SrcName()), + Expr: &FieldRef{Name: f.SrcName()}, + } + return newExpressionSize(sizeFun, elsz.exact) + } else { + return newExpressionSize(simpleLen, elsz.exact) + } + case *Union: + return newExpressionSize(simpleLen, elsz.exact) + case *Base: + return newExpressionSize(simpleLen, elsz.exact) + case *Resource: + return newExpressionSize(simpleLen, elsz.exact) + case *TypeDef: + return newExpressionSize(simpleLen, elsz.exact) + default: + log.Panicf("Cannot compute list size with type '%T'.", f.Type) + } + panic("unreachable") +} + +func (f *ListField) Initialize(p *Protocol) { + f.srcName = SrcName(p, f.XmlName()) + f.Type = f.Type.(*Translation).RealType(p) + if f.LengthExpr != nil { + f.LengthExpr.Initialize(p) + } +} + +// LocalField is exactly the same as a regular SingleField, except it isn't +// sent over the wire. (i.e., it's probably used to compute an ExprField). +type LocalField struct { + *SingleField +} + +// ExprField is a field that is not parameterized, but is computed from values +// of other fields. +type ExprField struct { + srcName string + xmlName string + Type Type + Expr Expression +} + +func (f *ExprField) SrcName() string { + return f.srcName +} + +func (f *ExprField) XmlName() string { + return f.xmlName +} + +func (f *ExprField) SrcType() string { + return f.Type.SrcName() +} + +func (f *ExprField) Size() Size { + return f.Type.Size() +} + +func (f *ExprField) Initialize(p *Protocol) { + f.srcName = SrcName(p, f.XmlName()) + f.Type = f.Type.(*Translation).RealType(p) + f.Expr.Initialize(p) +} + +// ValueField represents two fields in one: a mask and a list of 4-byte +// integers. The mask specifies which kinds of values are in the list. +// (i.e., See ConfigureWindow, CreateWindow, ChangeWindowAttributes, etc.) +type ValueField struct { + Parent interface{} + MaskType Type + MaskName string + ListName string +} + +func (f *ValueField) SrcName() string { + panic("it is illegal to call SrcName on a ValueField field") +} + +func (f *ValueField) XmlName() string { + panic("it is illegal to call XmlName on a ValueField field") +} + +func (f *ValueField) SrcType() string { + return f.MaskType.SrcName() +} + +// Size computes the size in bytes of the combination of the mask and list +// in this value field. +// The expression to compute this looks complicated, but it's really just +// the number of bits set in the mask multiplied 4 (and padded of course). +func (f *ValueField) Size() Size { + maskSize := f.MaskType.Size() + listSize := newExpressionSize(&Function{ + Name: "xgb.Pad", + Expr: &BinaryOp{ + Op: "*", + Expr1: &Value{v: 4}, + Expr2: &PopCount{ + Expr: &Function{ + Name: "int", + Expr: &FieldRef{ + Name: f.MaskName, + }, + }, + }, + }, + }, true) + return maskSize.Add(listSize) +} + +func (f *ValueField) ListLength() Size { + return newExpressionSize(&PopCount{ + Expr: &Function{ + Name: "int", + Expr: &FieldRef{ + Name: f.MaskName, + }, + }, + }, true) +} + +func (f *ValueField) Initialize(p *Protocol) { + f.MaskType = f.MaskType.(*Translation).RealType(p) + f.MaskName = SrcName(p, f.MaskName) + f.ListName = SrcName(p, f.ListName) +} + +// SwitchField represents a 'switch' element in the XML protocol description +// file. +// Currently we translate this to a slice of uint32 and let the user sort +// through it. +type SwitchField struct { + xmlName string + Name string + MaskName string + Expr Expression + Bitcases []*Bitcase +} + +func (f *SwitchField) SrcName() string { + return f.Name +} + +func (f *SwitchField) XmlName() string { + return f.xmlName +} + +func (f *SwitchField) SrcType() string { + return "[]uint32" +} + +func (f *SwitchField) Size() Size { + // TODO: size expression used here is not correct unless every element of + // the switch is 32 bit long. This assumption holds for xproto but may not + // hold for other protocols (xkb?) + listSize := newExpressionSize(&Function{ + Name: "xgb.Pad", + Expr: &BinaryOp{ + Op: "*", + Expr1: &Value{v: 4}, + Expr2: &PopCount{ + Expr: &Function{ + Name: "int", + Expr: &FieldRef{ + Name: f.MaskName, + }, + }, + }, + }, + }, true) + + return listSize +} + +func (f *SwitchField) ListLength() Size { + return newExpressionSize(&PopCount{ + Expr: &Function{ + Name: "int", + Expr: &FieldRef{ + Name: f.MaskName, + }, + }, + }, true) +} + +func (f *SwitchField) Initialize(p *Protocol) { + f.xmlName = f.Name + f.Name = SrcName(p, f.Name) + f.Expr.Initialize(p) + fieldref, ok := f.Expr.(*FieldRef) + if !ok { + panic("switch field's expression not a fieldref") + } + f.MaskName = SrcName(p, fieldref.Name) + for _, bitcase := range f.Bitcases { + bitcase.Expr.Initialize(p) + for _, field := range bitcase.Fields { + field.Initialize(p) + } + } +} + +// Bitcase represents a single bitcase inside a switch expression. +// It is not currently used. (i.e., it's XKB voodoo.) +type Bitcase struct { + Fields []Field + Expr Expression +} diff --git a/vend/xgb/xgbgen/go.go b/vend/xgb/xgbgen/go.go new file mode 100644 index 0000000..87b5028 --- /dev/null +++ b/vend/xgb/xgbgen/go.go @@ -0,0 +1,220 @@ +package main + +import ( + "fmt" +) + +// BaseTypeMap is a map from X base types to Go types. +// X base types should correspond to the smallest set of X types +// that can be used to rewrite ALL X types in terms of Go types. +// That is, if you remove any of the following types, at least one +// XML protocol description will produce an invalid Go program. +// The types on the left *never* show themselves in the source. +var BaseTypeMap = map[string]string{ + "CARD8": "byte", + "CARD16": "uint16", + "CARD32": "uint32", + "INT8": "int8", + "INT16": "int16", + "INT32": "int32", + "BYTE": "byte", + "BOOL": "bool", + "float": "float64", + "double": "float64", + "char": "byte", + "void": "byte", +} + +// BaseTypeSizes should have precisely the same keys as in BaseTypeMap, +// and the values should correspond to the size of the type in bytes. +var BaseTypeSizes = map[string]uint{ + "CARD8": 1, + "CARD16": 2, + "CARD32": 4, + "INT8": 1, + "INT16": 2, + "INT32": 4, + "BYTE": 1, + "BOOL": 1, + "float": 4, + "double": 8, + "char": 1, + "void": 1, + + // Id is a special type used to determine the size of all Xid types. + // "Id" is not actually written in the source. + "Id": 4, +} + +// TypeMap is a map from types in the XML to type names that is used +// in the functions that follow. Basically, every occurrence of the key +// type is replaced with the value type. +var TypeMap = map[string]string{ + "VISUALTYPE": "VisualInfo", + "DEPTH": "DepthInfo", + "SCREEN": "ScreenInfo", + "Setup": "SetupInfo", +} + +// NameMap is the same as TypeMap, but for names. +var NameMap = map[string]string{} + +// Reading, writing and defining... + +// Base types +func (b *Base) Define(c *Context) { + c.Putln("// Skipping definition for base type '%s'", + SrcName(c.protocol, b.XmlName())) + c.Putln("") +} + +// Enum types +func (enum *Enum) Define(c *Context) { + c.Putln("const (") + for _, item := range enum.Items { + c.Putln("%s%s = %d", enum.SrcName(), item.srcName, item.Expr.Eval()) + } + c.Putln(")") + c.Putln("") +} + +// Resource types +func (res *Resource) Define(c *Context) { + c.Putln("type %s uint32", res.SrcName()) + c.Putln("") + c.Putln("func New%sId(c *xgb.Conn) (%s, error) {", + res.SrcName(), res.SrcName()) + c.Putln("id, err := c.NewId()") + c.Putln("if err != nil {") + c.Putln("return 0, err") + c.Putln("}") + c.Putln("return %s(id), nil", res.SrcName()) + c.Putln("}") + c.Putln("") +} + +// TypeDef types +func (td *TypeDef) Define(c *Context) { + c.Putln("type %s %s", td.srcName, td.Old.SrcName()) + c.Putln("") +} + +// Field definitions, reads and writes. + +// Pad fields +func (f *PadField) Define(c *Context) { + if f.Align > 0 { + c.Putln("// alignment gap to multiple of %d", f.Align) + } else { + c.Putln("// padding: %d bytes", f.Bytes) + } +} + +func (f *PadField) Read(c *Context, prefix string) { + if f.Align > 0 { + c.Putln("b = (b + %d) & ^%d // alignment gap", f.Align-1, f.Align-1) + } else { + c.Putln("b += %s // padding", f.Size()) + } +} + +func (f *PadField) Write(c *Context, prefix string) { + if f.Align > 0 { + c.Putln("b = (b + %d) & ^%d // alignment gap", f.Align-1, f.Align-1) + } else { + c.Putln("b += %s // padding", f.Size()) + } +} + +// Local fields +func (f *LocalField) Define(c *Context) { + c.Putln("// local field: %s %s", f.SrcName(), f.Type.SrcName()) + panic("unreachable") +} + +func (f *LocalField) Read(c *Context, prefix string) { + c.Putln("// reading local field: %s (%s) :: %s", + f.SrcName(), f.Size(), f.Type.SrcName()) + panic("unreachable") +} + +func (f *LocalField) Write(c *Context, prefix string) { + c.Putln("// skip writing local field: %s (%s) :: %s", + f.SrcName(), f.Size(), f.Type.SrcName()) +} + +// Expr fields +func (f *ExprField) Define(c *Context) { + c.Putln("// expression field: %s %s (%s)", + f.SrcName(), f.Type.SrcName(), f.Expr) + panic("unreachable") +} + +func (f *ExprField) Read(c *Context, prefix string) { + c.Putln("// reading expression field: %s (%s) (%s) :: %s", + f.SrcName(), f.Size(), f.Expr, f.Type.SrcName()) + panic("unreachable") +} + +func (f *ExprField) Write(c *Context, prefix string) { + // Special case for bools, grrr. + if f.Type.SrcName() == "bool" { + c.Putln("buf[b] = byte(%s)", f.Expr.Reduce(prefix)) + c.Putln("b += 1") + } else { + WriteSimpleSingleField(c, f.Expr.Reduce(prefix), f.Type) + } +} + +// Value field +func (f *ValueField) Define(c *Context) { + c.Putln("%s %s", f.MaskName, f.SrcType()) + c.Putln("%s []uint32", f.ListName) +} + +func (f *ValueField) Read(c *Context, prefix string) { + ReadSimpleSingleField(c, + fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType) + c.Putln("") + c.Putln("%s%s = make([]uint32, %s)", + prefix, f.ListName, f.ListLength().Reduce(prefix)) + c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) + c.Putln("%s%s[i] = xgb.Get32(buf[b:])", prefix, f.ListName) + c.Putln("b += 4") + c.Putln("}") + c.Putln("b = xgb.Pad(b)") +} + +func (f *ValueField) Write(c *Context, prefix string) { + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType) + c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) + c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.ListName) + c.Putln("b += 4") + c.Putln("}") + c.Putln("b = xgb.Pad(b)") +} + +// Switch field +func (f *SwitchField) Define(c *Context) { + c.Putln("%s []uint32", f.Name) +} + +func (f *SwitchField) Read(c *Context, prefix string) { + c.Putln("") + c.Putln("%s%s = make([]uint32, %s)", + prefix, f.Name, f.ListLength().Reduce(prefix)) + c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) + c.Putln("%s%s[i] = xgb.Get32(buf[b:])", prefix, f.Name) + c.Putln("b += 4") + c.Putln("}") + c.Putln("b = xgb.Pad(b)") +} + +func (f *SwitchField) Write(c *Context, prefix string) { + c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) + c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.Name) + c.Putln("b += 4") + c.Putln("}") + c.Putln("b = xgb.Pad(b)") +} diff --git a/vend/xgb/xgbgen/go_error.go b/vend/xgb/xgbgen/go_error.go new file mode 100644 index 0000000..55fd28b --- /dev/null +++ b/vend/xgb/xgbgen/go_error.go @@ -0,0 +1,179 @@ +package main + +import ( + "fmt" +) + +// Error types +func (e *Error) Define(c *Context) { + c.Putln("// %s is the error number for a %s.", e.ErrConst(), e.ErrConst()) + c.Putln("const %s = %d", e.ErrConst(), e.Number) + c.Putln("") + c.Putln("type %s struct {", e.ErrType()) + c.Putln("Sequence uint16") + c.Putln("NiceName string") + for _, field := range e.Fields { + field.Define(c) + } + c.Putln("}") + c.Putln("") + + // Read defines a function that transforms a byte slice into this + // error struct. + e.Read(c) + + // Makes sure this error type implements the xgb.Error interface. + e.ImplementsError(c) + + // Let's the XGB event loop read this error. + c.Putln("func init() {") + if c.protocol.isExt() { + c.Putln("xgb.NewExtErrorFuncs[\"%s\"][%d] = %sNew", + c.protocol.ExtXName, e.Number, e.ErrType()) + } else { + c.Putln("xgb.NewErrorFuncs[%d] = %sNew", e.Number, e.ErrType()) + } + c.Putln("}") + c.Putln("") +} + +func (e *Error) Read(c *Context) { + c.Putln("// %sNew constructs a %s value that implements xgb.Error from "+ + "a byte slice.", e.ErrType(), e.ErrType()) + c.Putln("func %sNew(buf []byte) xgb.Error {", e.ErrType()) + c.Putln("v := %s{}", e.ErrType()) + c.Putln("v.NiceName = \"%s\"", e.SrcName()) + c.Putln("") + c.Putln("b := 1 // skip error determinant") + c.Putln("b += 1 // don't read error number") + c.Putln("") + c.Putln("v.Sequence = xgb.Get16(buf[b:])") + c.Putln("b += 2") + c.Putln("") + for _, field := range e.Fields { + field.Read(c, "v.") + c.Putln("") + } + c.Putln("return v") + c.Putln("}") + c.Putln("") +} + +// ImplementsError writes functions to implement the XGB Error interface. +func (e *Error) ImplementsError(c *Context) { + c.Putln("// SequenceId returns the sequence id attached to the %s error.", + e.ErrConst()) + c.Putln("// This is mostly used internally.") + c.Putln("func (err %s) SequenceId() uint16 {", e.ErrType()) + c.Putln("return err.Sequence") + c.Putln("}") + c.Putln("") + c.Putln("// BadId returns the 'BadValue' number if one exists for the "+ + "%s error. If no bad value exists, 0 is returned.", e.ErrConst()) + c.Putln("func (err %s) BadId() uint32 {", e.ErrType()) + if !c.protocol.isExt() { + c.Putln("return err.BadValue") + } else { + c.Putln("return 0") + } + c.Putln("}") + c.Putln("// Error returns a rudimentary string representation of the %s "+ + "error.", e.ErrConst()) + c.Putln("") + c.Putln("func (err %s) Error() string {", e.ErrType()) + ErrorFieldString(c, e.Fields, e.ErrConst()) + c.Putln("}") + c.Putln("") +} + +// ErrorCopy types +func (e *ErrorCopy) Define(c *Context) { + c.Putln("// %s is the error number for a %s.", e.ErrConst(), e.ErrConst()) + c.Putln("const %s = %d", e.ErrConst(), e.Number) + c.Putln("") + c.Putln("type %s %s", e.ErrType(), e.Old.(*Error).ErrType()) + c.Putln("") + + // Read defines a function that transforms a byte slice into this + // error struct. + e.Read(c) + + // Makes sure this error type implements the xgb.Error interface. + e.ImplementsError(c) + + // Let's the XGB know how to read this error. + c.Putln("func init() {") + if c.protocol.isExt() { + c.Putln("xgb.NewExtErrorFuncs[\"%s\"][%d] = %sNew", + c.protocol.ExtXName, e.Number, e.ErrType()) + } else { + c.Putln("xgb.NewErrorFuncs[%d] = %sNew", e.Number, e.ErrType()) + } + c.Putln("}") + c.Putln("") +} + +func (e *ErrorCopy) Read(c *Context) { + c.Putln("// %sNew constructs a %s value that implements xgb.Error from "+ + "a byte slice.", e.ErrType(), e.ErrType()) + c.Putln("func %sNew(buf []byte) xgb.Error {", e.ErrType()) + c.Putln("v := %s(%sNew(buf).(%s))", + e.ErrType(), e.Old.(*Error).ErrType(), e.Old.(*Error).ErrType()) + c.Putln("v.NiceName = \"%s\"", e.SrcName()) + c.Putln("return v") + c.Putln("}") + c.Putln("") +} + +// ImplementsError writes functions to implement the XGB Error interface. +func (e *ErrorCopy) ImplementsError(c *Context) { + c.Putln("// SequenceId returns the sequence id attached to the %s error.", + e.ErrConst()) + c.Putln("// This is mostly used internally.") + c.Putln("func (err %s) SequenceId() uint16 {", e.ErrType()) + c.Putln("return err.Sequence") + c.Putln("}") + c.Putln("") + c.Putln("// BadId returns the 'BadValue' number if one exists for the "+ + "%s error. If no bad value exists, 0 is returned.", e.ErrConst()) + c.Putln("func (err %s) BadId() uint32 {", e.ErrType()) + if !c.protocol.isExt() { + c.Putln("return err.BadValue") + } else { + c.Putln("return 0") + } + c.Putln("}") + c.Putln("") + c.Putln("// Error returns a rudimentary string representation of the %s "+ + "error.", e.ErrConst()) + c.Putln("func (err %s) Error() string {", e.ErrType()) + ErrorFieldString(c, e.Old.(*Error).Fields, e.ErrConst()) + c.Putln("}") + c.Putln("") +} + +// ErrorFieldString works for both Error and ErrorCopy. It assembles all of the +// fields in an error and formats them into a single string. +func ErrorFieldString(c *Context, fields []Field, errName string) { + c.Putln("fieldVals := make([]string, 0, %d)", len(fields)) + c.Putln("fieldVals = append(fieldVals, \"NiceName: \" + err.NiceName)") + c.Putln("fieldVals = append(fieldVals, "+ + "xgb.Sprintf(\"Sequence: %s\", err.Sequence))", "%d") + for _, field := range fields { + switch field.(type) { + case *PadField: + continue + default: + if field.SrcType() == "string" { + c.Putln("fieldVals = append(fieldVals, \"%s: \" + err.%s)", + field.SrcName(), field.SrcName()) + } else { + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", err.%s)", + field.SrcName(), "%d", field.SrcName()) + c.Putln("fieldVals = append(fieldVals, %s)", format) + } + } + } + c.Putln("return \"%s {\" + xgb.StringsJoin(fieldVals, \", \") + \"}\"", + errName) +} diff --git a/vend/xgb/xgbgen/go_event.go b/vend/xgb/xgbgen/go_event.go new file mode 100644 index 0000000..a4ed3ea --- /dev/null +++ b/vend/xgb/xgbgen/go_event.go @@ -0,0 +1,211 @@ +package main + +import ( + "fmt" +) + +// Event types +func (e *Event) Define(c *Context) { + c.Putln("// %s is the event number for a %s.", e.SrcName(), e.EvType()) + c.Putln("const %s = %d", e.SrcName(), e.Number) + c.Putln("") + c.Putln("type %s struct {", e.EvType()) + if !e.NoSequence { + c.Putln("Sequence uint16") + } + for _, field := range e.Fields { + field.Define(c) + } + c.Putln("}") + c.Putln("") + + // Read defines a function that transforms a byte slice into this + // event struct. + e.Read(c) + + // Write defines a function that transforms this event struct into + // a byte slice. + e.Write(c) + + // Makes sure that this event type is an Event interface. + c.Putln("// SequenceId returns the sequence id attached to the %s event.", + e.SrcName()) + c.Putln("// Events without a sequence number (KeymapNotify) return 0.") + c.Putln("// This is mostly used internally.") + c.Putln("func (v %s) SequenceId() uint16 {", e.EvType()) + if e.NoSequence { + c.Putln("return uint16(0)") + } else { + c.Putln("return v.Sequence") + } + c.Putln("}") + c.Putln("") + c.Putln("// String is a rudimentary string representation of %s.", + e.EvType()) + c.Putln("func (v %s) String() string {", e.EvType()) + EventFieldString(c, e.Fields, e.SrcName()) + c.Putln("}") + c.Putln("") + + // Let's the XGB event loop read this event. + c.Putln("func init() {") + if c.protocol.isExt() { + c.Putln("xgb.NewExtEventFuncs[\"%s\"][%d] = %sNew", + c.protocol.ExtXName, e.Number, e.EvType()) + } else { + c.Putln("xgb.NewEventFuncs[%d] = %sNew", e.Number, e.EvType()) + } + c.Putln("}") + c.Putln("") +} + +func (e *Event) Read(c *Context) { + c.Putln("// %sNew constructs a %s value that implements xgb.Event from "+ + "a byte slice.", e.EvType(), e.EvType()) + c.Putln("func %sNew(buf []byte) xgb.Event {", e.EvType()) + c.Putln("v := %s{}", e.EvType()) + c.Putln("b := 1 // don't read event number") + c.Putln("") + for i, field := range e.Fields { + if i == 1 && !e.NoSequence { + c.Putln("v.Sequence = xgb.Get16(buf[b:])") + c.Putln("b += 2") + c.Putln("") + } + field.Read(c, "v.") + c.Putln("") + } + c.Putln("return v") + c.Putln("}") + c.Putln("") +} + +func (e *Event) Write(c *Context) { + c.Putln("// Bytes writes a %s value to a byte slice.", e.EvType()) + c.Putln("func (v %s) Bytes() []byte {", e.EvType()) + c.Putln("buf := make([]byte, %s)", e.Size()) + c.Putln("b := 0") + c.Putln("") + c.Putln("// write event number") + c.Putln("buf[b] = %d", e.Number) + c.Putln("b += 1") + c.Putln("") + for i, field := range e.Fields { + if i == 1 && !e.NoSequence { + c.Putln("b += 2 // skip sequence number") + c.Putln("") + } + field.Write(c, "v.") + c.Putln("") + } + c.Putln("return buf") + c.Putln("}") + c.Putln("") +} + +// EventCopy types +func (e *EventCopy) Define(c *Context) { + c.Putln("// %s is the event number for a %s.", e.SrcName(), e.EvType()) + c.Putln("const %s = %d", e.SrcName(), e.Number) + c.Putln("") + c.Putln("type %s %s", e.EvType(), e.Old.(*Event).EvType()) + c.Putln("") + + // Read defines a function that transforms a byte slice into this + // event struct. + e.Read(c) + + // Write defines a function that transoforms this event struct into + // a byte slice. + e.Write(c) + + // Makes sure that this event type is an Event interface. + c.Putln("// SequenceId returns the sequence id attached to the %s event.", + e.SrcName()) + c.Putln("// Events without a sequence number (KeymapNotify) return 0.") + c.Putln("// This is mostly used internally.") + c.Putln("func (v %s) SequenceId() uint16 {", e.EvType()) + if e.Old.(*Event).NoSequence { + c.Putln("return uint16(0)") + } else { + c.Putln("return v.Sequence") + } + c.Putln("}") + c.Putln("") + c.Putln("func (v %s) String() string {", e.EvType()) + EventFieldString(c, e.Old.(*Event).Fields, e.SrcName()) + c.Putln("}") + c.Putln("") + + // Let's the XGB event loop read this event. + c.Putln("func init() {") + if c.protocol.isExt() { + c.Putln("xgb.NewExtEventFuncs[\"%s\"][%d] = %sNew", + c.protocol.ExtXName, e.Number, e.EvType()) + } else { + c.Putln("xgb.NewEventFuncs[%d] = %sNew", e.Number, e.EvType()) + } + c.Putln("}") + c.Putln("") +} + +func (e *EventCopy) Read(c *Context) { + c.Putln("// %sNew constructs a %s value that implements xgb.Event from "+ + "a byte slice.", e.EvType(), e.EvType()) + c.Putln("func %sNew(buf []byte) xgb.Event {", e.EvType()) + c.Putln("return %s(%sNew(buf).(%s))", + e.EvType(), e.Old.(*Event).EvType(), e.Old.(*Event).EvType()) + c.Putln("}") + c.Putln("") +} + +func (e *EventCopy) Write(c *Context) { + c.Putln("// Bytes writes a %s value to a byte slice.", e.EvType()) + c.Putln("func (v %s) Bytes() []byte {", e.EvType()) + c.Putln("buf := %s(v).Bytes()", e.Old.(*Event).EvType()) + c.Putln("buf[0] = %d", e.Number) + c.Putln("return buf") + c.Putln("}") + c.Putln("") +} + +// EventFieldString works for both Event and EventCopy. It assembles all of the +// fields in an event and formats them into a single string. +func EventFieldString(c *Context, fields []Field, evName string) { + c.Putln("fieldVals := make([]string, 0, %d)", len(fields)) + if evName != "KeymapNotify" { + c.Putln("fieldVals = append(fieldVals, "+ + "xgb.Sprintf(\"Sequence: %s\", v.Sequence))", "%d") + } + for _, field := range fields { + switch f := field.(type) { + case *PadField: + continue + case *SingleField: + switch f.Type.(type) { + case *Base: + case *Resource: + case *TypeDef: + default: + continue + } + + switch field.SrcType() { + case "string": + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", v.%s)", + field.SrcName(), "%s", field.SrcName()) + c.Putln("fieldVals = append(fieldVals, %s)", format) + case "bool": + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", v.%s)", + field.SrcName(), "%t", field.SrcName()) + c.Putln("fieldVals = append(fieldVals, %s)", format) + default: + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", v.%s)", + field.SrcName(), "%d", field.SrcName()) + c.Putln("fieldVals = append(fieldVals, %s)", format) + } + } + } + c.Putln("return \"%s {\" + xgb.StringsJoin(fieldVals, \", \") + \"}\"", + evName) +} diff --git a/vend/xgb/xgbgen/go_list.go b/vend/xgb/xgbgen/go_list.go new file mode 100644 index 0000000..1e85d9f --- /dev/null +++ b/vend/xgb/xgbgen/go_list.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "log" + "strings" +) + +// List fields +func (f *ListField) Define(c *Context) { + c.Putln("%s %s // size: %s", + f.SrcName(), f.SrcType(), f.Size()) +} + +func (f *ListField) Read(c *Context, prefix string) { + switch t := f.Type.(type) { + case *Resource: + length := f.LengthExpr.Reduce(prefix) + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("for i := 0; i < int(%s); i++ {", length) + ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Base: + length := f.LengthExpr.Reduce(prefix) + if strings.ToLower(t.XmlName()) == "char" { + c.Putln("{") + c.Putln("byteString := make([]%s, %s)", t.SrcName(), length) + c.Putln("copy(byteString[:%s], buf[b:])", length) + c.Putln("%s%s = string(byteString)", prefix, f.SrcName()) + // This is apparently a special case. The "Str" type itself + // doesn't specify any padding. I suppose it's up to the + // request/reply spec that uses it to get the padding right? + c.Putln("b += int(%s)", length) + c.Putln("}") + } else if t.SrcName() == "byte" { + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("copy(%s%s[:%s], buf[b:])", prefix, f.SrcName(), length) + c.Putln("b += int(%s)", length) + } else { + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("for i := 0; i < int(%s); i++ {", length) + ReadSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + } + case *TypeDef: + length := f.LengthExpr.Reduce(prefix) + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("for i := 0; i < int(%s); i++ {", length) + ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Union: + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix)) + c.Putln("b += %sReadList(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + case *Struct: + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix)) + c.Putln("b += %sReadList(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + default: + log.Panicf("Cannot read list field '%s' with %T type.", + f.XmlName(), f.Type) + } +} + +func (f *ListField) Write(c *Context, prefix string) { + switch t := f.Type.(type) { + case *Resource: + length := f.Length().Reduce(prefix) + c.Putln("for i := 0; i < int(%s); i++ {", length) + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Base: + length := f.Length().Reduce(prefix) + if t.SrcName() == "byte" { + c.Putln("copy(buf[b:], %s%s[:%s])", prefix, f.SrcName(), length) + c.Putln("b += int(%s)", length) + } else { + c.Putln("for i := 0; i < int(%s); i++ {", length) + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + } + case *TypeDef: + length := f.Length().Reduce(prefix) + c.Putln("for i := 0; i < int(%s); i++ {", length) + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Union: + c.Putln("b += %sListBytes(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + case *Struct: + c.Putln("b += %sListBytes(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + default: + log.Panicf("Cannot write list field '%s' with %T type.", + f.XmlName(), f.Type) + } +} diff --git a/vend/xgb/xgbgen/go_request_reply.go b/vend/xgb/xgbgen/go_request_reply.go new file mode 100644 index 0000000..9cadc33 --- /dev/null +++ b/vend/xgb/xgbgen/go_request_reply.go @@ -0,0 +1,242 @@ +package main + +import ( + "fmt" + "strings" +) + +func (r *Request) Define(c *Context) { + c.Putln("// %s is a cookie used only for %s requests.", + r.CookieName(), r.SrcName()) + c.Putln("type %s struct {", r.CookieName()) + c.Putln("*xgb.Cookie") + c.Putln("}") + c.Putln("") + if r.Reply != nil { + c.Putln("// %s sends a checked request.", r.SrcName()) + c.Putln("// If an error occurs, it will be returned with the reply "+ + "by calling %s.Reply()", r.CookieName()) + c.Putln("func %s(c *xgb.Conn, %s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + r.CheckExt(c) + c.Putln("cookie := c.NewCookie(true, true)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s{cookie}", r.CookieName()) + c.Putln("}") + c.Putln("") + + c.Putln("// %sUnchecked sends an unchecked request.", r.SrcName()) + c.Putln("// If an error occurs, it can only be retrieved using " + + "xgb.WaitForEvent or xgb.PollForEvent.") + c.Putln("func %sUnchecked(c *xgb.Conn, %s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + r.CheckExt(c) + c.Putln("cookie := c.NewCookie(false, true)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s{cookie}", r.CookieName()) + c.Putln("}") + c.Putln("") + + r.ReadReply(c) + } else { + c.Putln("// %s sends an unchecked request.", r.SrcName()) + c.Putln("// If an error occurs, it can only be retrieved using " + + "xgb.WaitForEvent or xgb.PollForEvent.") + c.Putln("func %s(c *xgb.Conn, %s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + r.CheckExt(c) + c.Putln("cookie := c.NewCookie(false, false)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s{cookie}", r.CookieName()) + c.Putln("}") + c.Putln("") + + c.Putln("// %sChecked sends a checked request.", r.SrcName()) + c.Putln("// If an error occurs, it can be retrieved using "+ + "%s.Check()", r.CookieName()) + c.Putln("func %sChecked(c *xgb.Conn, %s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + r.CheckExt(c) + c.Putln("cookie := c.NewCookie(true, false)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s{cookie}", r.CookieName()) + c.Putln("}") + c.Putln("") + + c.Putln("// Check returns an error if one occurred for checked " + + "requests that are not expecting a reply.") + c.Putln("// This cannot be called for requests expecting a reply, " + + "nor for unchecked requests.") + c.Putln("func (cook %s) Check() error {", r.CookieName()) + c.Putln("return cook.Cookie.Check()") + c.Putln("}") + c.Putln("") + } + r.WriteRequest(c) +} + +func (r *Request) CheckExt(c *Context) { + if !c.protocol.isExt() { + return + } + c.Putln("c.ExtLock.RLock()") + c.Putln("defer c.ExtLock.RUnlock()") + c.Putln("if _, ok := c.Extensions[\"%s\"]; !ok {", c.protocol.ExtXName) + c.Putln("panic(\"Cannot issue request '%s' using the uninitialized "+ + "extension '%s'. %s.Init(connObj) must be called first.\")", + r.SrcName(), c.protocol.ExtXName, c.protocol.PkgName()) + c.Putln("}") +} + +func (r *Request) ReadReply(c *Context) { + c.Putln("// %s represents the data returned from a %s request.", + r.ReplyTypeName(), r.SrcName()) + c.Putln("type %s struct {", r.ReplyTypeName()) + c.Putln("Sequence uint16 // sequence number of the request for this reply") + c.Putln("Length uint32 // number of bytes in this reply") + for _, field := range r.Reply.Fields { + field.Define(c) + } + c.Putln("}") + c.Putln("") + + c.Putln("// Reply blocks and returns the reply data for a %s request.", + r.SrcName()) + c.Putln("func (cook %s) Reply() (*%s, error) {", + r.CookieName(), r.ReplyTypeName()) + c.Putln("buf, err := cook.Cookie.Reply()") + c.Putln("if err != nil {") + c.Putln("return nil, err") + c.Putln("}") + c.Putln("if buf == nil {") + c.Putln("return nil, nil") + c.Putln("}") + c.Putln("return %s(buf), nil", r.ReplyName()) + c.Putln("}") + c.Putln("") + + c.Putln("// %s reads a byte slice into a %s value.", + r.ReplyName(), r.ReplyTypeName()) + c.Putln("func %s(buf []byte) *%s {", + r.ReplyName(), r.ReplyTypeName()) + c.Putln("v := new(%s)", r.ReplyTypeName()) + c.Putln("b := 1 // skip reply determinant") + c.Putln("") + for i, field := range r.Reply.Fields { + field.Read(c, "v.") + c.Putln("") + if i == 0 { + c.Putln("v.Sequence = xgb.Get16(buf[b:])") + c.Putln("b += 2") + c.Putln("") + c.Putln("v.Length = xgb.Get32(buf[b:]) // 4-byte units") + c.Putln("b += 4") + c.Putln("") + } + } + c.Putln("return v") + c.Putln("}") + c.Putln("") +} + +func (r *Request) WriteRequest(c *Context) { + sz := r.Size(c) + writeSize1 := func() { + if sz.exact { + c.Putln("xgb.Put16(buf[b:], uint16(size / 4)) " + + "// write request size in 4-byte units") + } else { + c.Putln("blen := b") + } + c.Putln("b += 2") + c.Putln("") + } + writeSize2 := func() { + if sz.exact { + c.Putln("return buf") + return + } + c.Putln("b = xgb.Pad(b)") + c.Putln("xgb.Put16(buf[blen:], uint16(b / 4)) " + + "// write request size in 4-byte units") + c.Putln("return buf[:b]") + } + c.Putln("// Write request to wire for %s", r.SrcName()) + c.Putln("// %s writes a %s request to a byte slice.", + r.ReqName(), r.SrcName()) + c.Putln("func %s(c *xgb.Conn, %s) []byte {", + r.ReqName(), r.ParamNameTypes()) + c.Putln("size := %s", sz) + c.Putln("b := 0") + c.Putln("buf := make([]byte, size)") + c.Putln("") + if c.protocol.isExt() { + c.Putln("c.ExtLock.RLock()") + c.Putln("buf[b] = c.Extensions[\"%s\"]", c.protocol.ExtXName) + c.Putln("c.ExtLock.RUnlock()") + c.Putln("b += 1") + c.Putln("") + } + c.Putln("buf[b] = %d // request opcode", r.Opcode) + c.Putln("b += 1") + c.Putln("") + if len(r.Fields) == 0 { + if !c.protocol.isExt() { + c.Putln("b += 1 // padding") + } + writeSize1() + } else if c.protocol.isExt() { + writeSize1() + } + for i, field := range r.Fields { + field.Write(c, "") + c.Putln("") + if i == 0 && !c.protocol.isExt() { + writeSize1() + } + } + writeSize2() + c.Putln("}") + c.Putln("") +} + +func (r *Request) ParamNames() string { + names := make([]string, 0, len(r.Fields)) + for _, field := range r.Fields { + switch f := field.(type) { + case *ValueField: + names = append(names, f.MaskName) + names = append(names, f.ListName) + case *PadField: + continue + case *ExprField: + continue + default: + names = append(names, fmt.Sprintf("%s", field.SrcName())) + } + } + return strings.Join(names, ", ") +} + +func (r *Request) ParamNameTypes() string { + nameTypes := make([]string, 0, len(r.Fields)) + for _, field := range r.Fields { + switch f := field.(type) { + case *ValueField: + nameTypes = append(nameTypes, + fmt.Sprintf("%s %s", f.MaskName, f.MaskType.SrcName())) + nameTypes = append(nameTypes, + fmt.Sprintf("%s []uint32", f.ListName)) + case *PadField: + continue + case *ExprField: + continue + case *RequiredStartAlign: + continue + default: + nameTypes = append(nameTypes, + fmt.Sprintf("%s %s", field.SrcName(), field.SrcType())) + } + } + return strings.Join(nameTypes, ", ") +} diff --git a/vend/xgb/xgbgen/go_single_field.go b/vend/xgb/xgbgen/go_single_field.go new file mode 100644 index 0000000..6c7218e --- /dev/null +++ b/vend/xgb/xgbgen/go_single_field.go @@ -0,0 +1,166 @@ +package main + +import ( + "fmt" + "log" +) + +func (f *SingleField) Define(c *Context) { + c.Putln("%s %s", f.SrcName(), f.Type.SrcName()) +} + +func ReadSimpleSingleField(c *Context, name string, typ Type) { + switch t := typ.(type) { + case *Resource: + c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName()) + case *TypeDef: + switch t.Size().Eval() { + case 1: + c.Putln("%s = %s(buf[b])", name, t.SrcName()) + case 2: + c.Putln("%s = %s(xgb.Get16(buf[b:]))", name, t.SrcName()) + case 4: + c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName()) + case 8: + c.Putln("%s = %s(xgb.Get64(buf[b:]))", name, t.SrcName()) + } + case *Base: + // If this is a bool, stop short and do something special. + if t.SrcName() == "bool" { + c.Putln("if buf[b] == 1 {") + c.Putln("%s = true", name) + c.Putln("} else {") + c.Putln("%s = false", name) + c.Putln("}") + break + } + + var val string + switch t.Size().Eval() { + case 1: + val = fmt.Sprintf("buf[b]") + case 2: + val = fmt.Sprintf("xgb.Get16(buf[b:])") + case 4: + val = fmt.Sprintf("xgb.Get32(buf[b:])") + case 8: + val = fmt.Sprintf("xgb.Get64(buf[b:])") + } + + // We need to convert base types if they aren't uintXX or byte + ty := t.SrcName() + if ty != "byte" && ty != "uint16" && ty != "uint32" && ty != "uint64" { + val = fmt.Sprintf("%s(%s)", ty, val) + } + c.Putln("%s = %s", name, val) + default: + log.Panicf("Cannot read field '%s' as a simple field with %T type.", + name, typ) + } + + c.Putln("b += %s", typ.Size()) +} + +func (f *SingleField) Read(c *Context, prefix string) { + switch t := f.Type.(type) { + case *Resource: + ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) + case *TypeDef: + ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) + case *Base: + ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) + case *Struct: + c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName()) + c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) + case *Union: + c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName()) + c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) + default: + log.Panicf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type) + } +} + +func WriteSimpleSingleField(c *Context, name string, typ Type) { + switch t := typ.(type) { + case *Resource: + c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) + case *TypeDef: + switch t.Size().Eval() { + case 1: + c.Putln("buf[b] = byte(%s)", name) + case 2: + c.Putln("xgb.Put16(buf[b:], uint16(%s))", name) + case 4: + c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) + case 8: + c.Putln("xgb.Put64(buf[b:], uint64(%s))", name) + } + case *Base: + // If this is a bool, stop short and do something special. + if t.SrcName() == "bool" { + c.Putln("if %s {", name) + c.Putln("buf[b] = 1") + c.Putln("} else {") + c.Putln("buf[b] = 0") + c.Putln("}") + break + } + + switch t.Size().Eval() { + case 1: + if t.SrcName() != "byte" { + c.Putln("buf[b] = byte(%s)", name) + } else { + c.Putln("buf[b] = %s", name) + } + case 2: + if t.SrcName() != "uint16" { + c.Putln("xgb.Put16(buf[b:], uint16(%s))", name) + } else { + c.Putln("xgb.Put16(buf[b:], %s)", name) + } + case 4: + if t.SrcName() != "uint32" { + c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) + } else { + c.Putln("xgb.Put32(buf[b:], %s)", name) + } + case 8: + if t.SrcName() != "uint64" { + c.Putln("xgb.Put64(buf[b:], uint64(%s))", name) + } else { + c.Putln("xgb.Put64(buf[b:], %s)", name) + } + } + default: + log.Fatalf("Cannot read field '%s' as a simple field with %T type.", + name, typ) + } + + c.Putln("b += %s", typ.Size()) +} + +func (f *SingleField) Write(c *Context, prefix string) { + switch t := f.Type.(type) { + case *Resource: + WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) + case *TypeDef: + WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) + case *Base: + WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) + case *Union: + c.Putln("{") + c.Putln("unionBytes := %s%s.Bytes()", prefix, f.SrcName()) + c.Putln("copy(buf[b:], unionBytes)") + c.Putln("b += len(unionBytes)") + c.Putln("}") + case *Struct: + c.Putln("{") + c.Putln("structBytes := %s%s.Bytes()", prefix, f.SrcName()) + c.Putln("copy(buf[b:], structBytes)") + c.Putln("b += len(structBytes)") + c.Putln("}") + default: + log.Fatalf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type) + } +} diff --git a/vend/xgb/xgbgen/go_struct.go b/vend/xgb/xgbgen/go_struct.go new file mode 100644 index 0000000..ee74d90 --- /dev/null +++ b/vend/xgb/xgbgen/go_struct.go @@ -0,0 +1,118 @@ +package main + +func (s *Struct) Define(c *Context) { + c.Putln("type %s struct {", s.SrcName()) + for _, field := range s.Fields { + field.Define(c) + } + c.Putln("}") + c.Putln("") + + // Write function that reads bytes and produces this struct. + s.Read(c) + + // Write function that reads bytes and produces a list of this struct. + s.ReadList(c) + + // Write function that writes bytes given this struct. + s.Write(c) + + // Write function that writes a list of this struct. + s.WriteList(c) + + // Write function that computes the size of a list of these structs, + // IF there is a list field in this struct. + if s.HasList() { + s.WriteListSize(c) + } +} + +// Read for a struct creates a function 'ReadStructName' that takes a source +// byte slice (i.e., the buffer) and a destination struct, and returns +// the number of bytes read off the buffer. +// 'ReadStructName' should only be used to read raw reply data from the wire. +func (s *Struct) Read(c *Context) { + c.Putln("// %sRead reads a byte slice into a %s value.", + s.SrcName(), s.SrcName()) + c.Putln("func %sRead(buf []byte, v *%s) int {", s.SrcName(), s.SrcName()) + + c.Putln("b := 0") + c.Putln("") + for _, field := range s.Fields { + field.Read(c, "v.") + c.Putln("") + } + c.Putln("return b") + + c.Putln("}") + c.Putln("") +} + +// ReadList for a struct creates a function 'ReadStructNameList' that takes +// a source (i.e., the buffer) byte slice, and a destination slice and returns +// the number of bytes read from the byte slice. +func (s *Struct) ReadList(c *Context) { + c.Putln("// %sReadList reads a byte slice into a list of %s values.", + s.SrcName(), s.SrcName()) + c.Putln("func %sReadList(buf []byte, dest []%s) int {", + s.SrcName(), s.SrcName()) + c.Putln("b := 0") + c.Putln("for i := 0; i < len(dest); i++ {") + c.Putln("dest[i] = %s{}", s.SrcName()) + c.Putln("b += %sRead(buf[b:], &dest[i])", s.SrcName()) + c.Putln("}") + + c.Putln("return xgb.Pad(b)") + + c.Putln("}") + c.Putln("") +} + +func (s *Struct) Write(c *Context) { + c.Putln("// Bytes writes a %s value to a byte slice.", s.SrcName()) + c.Putln("func (v %s) Bytes() []byte {", s.SrcName()) + c.Putln("buf := make([]byte, %s)", s.Size().Reduce("v.")) + c.Putln("b := 0") + c.Putln("") + for _, field := range s.Fields { + field.Write(c, "v.") + c.Putln("") + } + c.Putln("return buf[:b]") + c.Putln("}") + c.Putln("") +} + +func (s *Struct) WriteList(c *Context) { + c.Putln("// %sListBytes writes a list of %s values to a byte slice.", + s.SrcName(), s.SrcName()) + c.Putln("func %sListBytes(buf []byte, list []%s) int {", + s.SrcName(), s.SrcName()) + c.Putln("b := 0") + c.Putln("var structBytes []byte") + c.Putln("for _, item := range list {") + c.Putln("structBytes = item.Bytes()") + c.Putln("copy(buf[b:], structBytes)") + c.Putln("b += len(structBytes)") + c.Putln("}") + c.Putln("return xgb.Pad(b)") + c.Putln("}") + c.Putln("") +} + +func (s *Struct) WriteListSize(c *Context) { + c.Putln("// %sListSize computes the size (bytes) of a list of %s values.", + s.SrcName(), s.SrcName()) + c.Putln("func %sListSize(list []%s) int {", s.SrcName(), s.SrcName()) + c.Putln("size := 0") + if s.Size().Expression.Concrete() { + c.Putln("for _ = range list {") + } else { + c.Putln("for _, item := range list {") + } + c.Putln("size += %s", s.Size().Reduce("item.")) + c.Putln("}") + c.Putln("return size") + c.Putln("}") + c.Putln("") +} diff --git a/vend/xgb/xgbgen/go_union.go b/vend/xgb/xgbgen/go_union.go new file mode 100644 index 0000000..74816d3 --- /dev/null +++ b/vend/xgb/xgbgen/go_union.go @@ -0,0 +1,147 @@ +package main + +// Union types +func (u *Union) Define(c *Context) { + c.Putln("// %s is a represention of the %s union type.", + u.SrcName(), u.SrcName()) + c.Putln("// Note that to *create* a Union, you should *never* create") + c.Putln("// this struct directly (unless you know what you're doing).") + c.Putln("// Instead use one of the following constructors for '%s':", + u.SrcName()) + for _, field := range u.Fields { + c.Putln("// %s%sNew(%s %s) %s", u.SrcName(), field.SrcName(), + field.SrcName(), field.SrcType(), u.SrcName()) + } + + c.Putln("type %s struct {", u.SrcName()) + for _, field := range u.Fields { + field.Define(c) + } + c.Putln("}") + c.Putln("") + + // Write functions for each field that create instances of this + // union using the corresponding field. + u.New(c) + + // Write function that reads bytes and produces this union. + u.Read(c) + + // Write function that reads bytes and produces a list of this union. + u.ReadList(c) + + // Write function that writes bytes given this union. + u.Write(c) + + // Write function that writes a list of this union. + u.WriteList(c) +} + +func (u *Union) New(c *Context) { + for _, field := range u.Fields { + c.Putln("// %s%sNew constructs a new %s union type with the %s field.", + u.SrcName(), field.SrcName(), u.SrcName(), field.SrcName()) + c.Putln("func %s%sNew(%s %s) %s {", + u.SrcName(), field.SrcName(), field.SrcName(), + field.SrcType(), u.SrcName()) + c.Putln("var b int") + c.Putln("buf := make([]byte, %s)", u.Size()) + c.Putln("") + field.Write(c, "") + c.Putln("") + c.Putln("// Create the Union type") + c.Putln("v := %s{}", u.SrcName()) + c.Putln("") + c.Putln("// Now copy buf into all fields") + c.Putln("") + for _, field2 := range u.Fields { + c.Putln("b = 0 // always read the same bytes") + field2.Read(c, "v.") + c.Putln("") + } + c.Putln("return v") + c.Putln("}") + c.Putln("") + } +} + +func (u *Union) Read(c *Context) { + c.Putln("// %sRead reads a byte slice into a %s value.", + u.SrcName(), u.SrcName()) + c.Putln("func %sRead(buf []byte, v *%s) int {", u.SrcName(), u.SrcName()) + c.Putln("var b int") + c.Putln("") + for _, field := range u.Fields { + c.Putln("b = 0 // re-read the same bytes") + field.Read(c, "v.") + c.Putln("") + } + c.Putln("return %s", u.Size()) + c.Putln("}") + c.Putln("") +} + +func (u *Union) ReadList(c *Context) { + c.Putln("// %sReadList reads a byte slice into a list of %s values.", + u.SrcName(), u.SrcName()) + c.Putln("func %sReadList(buf []byte, dest []%s) int {", + u.SrcName(), u.SrcName()) + c.Putln("b := 0") + c.Putln("for i := 0; i < len(dest); i++ {") + c.Putln("dest[i] = %s{}", u.SrcName()) + c.Putln("b += %sRead(buf[b:], &dest[i])", u.SrcName()) + c.Putln("}") + c.Putln("return xgb.Pad(b)") + c.Putln("}") + c.Putln("") +} + +// This is a bit tricky since writing from a Union implies that only +// the data inside ONE of the elements is actually written. +// However, we only currently support unions where every field has the +// *same* *fixed* size. Thus, we make sure to always read bytes into +// every field which allows us to simply pick the first field and write it. +func (u *Union) Write(c *Context) { + c.Putln("// Bytes writes a %s value to a byte slice.", u.SrcName()) + c.Putln("// Each field in a union must contain the same data.") + c.Putln("// So simply pick the first field and write that to the wire.") + c.Putln("func (v %s) Bytes() []byte {", u.SrcName()) + c.Putln("buf := make([]byte, %s)", u.Size().Reduce("v.")) + c.Putln("b := 0") + c.Putln("") + u.Fields[0].Write(c, "v.") + c.Putln("return buf") + c.Putln("}") + c.Putln("") +} + +func (u *Union) WriteList(c *Context) { + c.Putln("// %sListBytes writes a list of %s values to a byte slice.", + u.SrcName(), u.SrcName()) + c.Putln("func %sListBytes(buf []byte, list []%s) int {", + u.SrcName(), u.SrcName()) + c.Putln("b := 0") + c.Putln("var unionBytes []byte") + c.Putln("for _, item := range list {") + c.Putln("unionBytes = item.Bytes()") + c.Putln("copy(buf[b:], unionBytes)") + c.Putln("b += xgb.Pad(len(unionBytes))") + c.Putln("}") + c.Putln("return b") + c.Putln("}") + c.Putln("") +} + +func (u *Union) WriteListSize(c *Context) { + c.Putln("// Union list size %s", u.SrcName()) + c.Putln("// %sListSize computes the size (bytes) of a list of %s values.", + u.SrcName()) + c.Putln("func %sListSize(list []%s) int {", u.SrcName(), u.SrcName()) + c.Putln("size := 0") + c.Putln("for _, item := range list {") + c.Putln("size += %s", u.Size().Reduce("item.")) + c.Putln("}") + c.Putln("return size") + c.Putln("}") + c.Putln("") +} diff --git a/vend/xgb/xgbgen/main.go b/vend/xgb/xgbgen/main.go new file mode 100644 index 0000000..fd5eac7 --- /dev/null +++ b/vend/xgb/xgbgen/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "flag" + "io/ioutil" + "log" + "os" + "os/exec" + "strings" +) + +var ( + protoPath = flag.String("proto-path", + "/usr/share/xcb", "path to directory of X protocol XML files") + gofmt = flag.Bool("gofmt", true, + "When disabled, gofmt will not be run before outputting Go code") +) + +func usage() { + basename := os.Args[0] + if lastSlash := strings.LastIndex(basename, "/"); lastSlash > -1 { + basename = basename[lastSlash+1:] + } + log.Printf("Usage: %s [flags] xml-file", basename) + flag.PrintDefaults() + os.Exit(1) +} + +func init() { + log.SetFlags(0) +} + +func main() { + flag.Usage = usage + flag.Parse() + + if flag.NArg() != 1 { + log.Printf("A single XML protocol file can be processed at once.") + flag.Usage() + } + + // Read the single XML file into []byte + xmlBytes, err := ioutil.ReadFile(flag.Arg(0)) + if err != nil { + log.Fatal(err) + } + + // Initialize the buffer, parse it, and filter it through gofmt. + c := newContext() + c.Morph(xmlBytes) + + if !*gofmt { + c.out.WriteTo(os.Stdout) + } else { + cmdGofmt := exec.Command("gofmt") + cmdGofmt.Stdin = c.out + cmdGofmt.Stdout = os.Stdout + cmdGofmt.Stderr = os.Stderr + err = cmdGofmt.Run() + if err != nil { + log.Fatal(err) + } + } +} diff --git a/vend/xgb/xgbgen/misc.go b/vend/xgb/xgbgen/misc.go new file mode 100644 index 0000000..85d788f --- /dev/null +++ b/vend/xgb/xgbgen/misc.go @@ -0,0 +1,49 @@ +package main + +import ( + "regexp" + "strings" +) + +// AllCaps is a regex to test if a string identifier is made of +// all upper case letters. +var allCaps = regexp.MustCompile("^[A-Z0-9]+$") + +// popCount counts number of bits 'set' in mask. +func popCount(mask uint) uint { + m := uint32(mask) + n := uint(0) + for i := uint32(0); i < 32; i++ { + if m&(1< 31 { + log.Panicf("A 'bit' literal must be in the range [0, 31], but "+ + " is %d", bit) + } + return &Bit{ + b: bit, + } + case "fieldref": + return &FieldRef{ + Name: x.Data, + } + case "enumref": + return &EnumRef{ + EnumKind: newTranslation(x.Ref), + EnumItem: x.Data, + } + case "sumof": + return &SumOf{ + Name: x.Ref, + } + } + + log.Panicf("Unrecognized tag '%s' in expression context. Expected one of "+ + "op, fieldref, value, bit, enumref, unop, sumof or popcount.", + x.XMLName.Local) + panic("unreachable") +} + +func (x *XMLField) Translate(parent interface{}) Field { + switch x.XMLName.Local { + case "pad": + return &PadField{ + Bytes: x.Bytes, + Align: x.Align, + } + case "field": + s := &SingleField{ + xmlName: x.Name, + Type: newTranslation(x.Type), + } + return s + case "list": + return &ListField{ + xmlName: x.Name, + Type: newTranslation(x.Type), + LengthExpr: x.Expr.Translate(), + } + case "localfield": + return &LocalField{&SingleField{ + xmlName: x.Name, + Type: newTranslation(x.Type), + }} + case "exprfield": + return &ExprField{ + xmlName: x.Name, + Type: newTranslation(x.Type), + Expr: x.Expr.Translate(), + } + case "valueparam": + return &ValueField{ + Parent: parent, + MaskType: newTranslation(x.ValueMaskType), + MaskName: x.ValueMaskName, + ListName: x.ValueListName, + } + case "switch": + swtch := &SwitchField{ + Name: x.Name, + Expr: x.Expr.Translate(), + Bitcases: make([]*Bitcase, len(x.Bitcases)), + } + for i, bitcase := range x.Bitcases { + swtch.Bitcases[i] = bitcase.Translate() + } + return swtch + case "required_start_align": + return &RequiredStartAlign{} + } + + log.Panicf("Unrecognized field element: %s", x.XMLName.Local) + panic("unreachable") +} + +func (x *XMLBitcase) Translate() *Bitcase { + b := &Bitcase{ + Expr: x.Expr().Translate(), + Fields: make([]Field, len(x.Fields)), + } + for i, field := range x.Fields { + b.Fields[i] = field.Translate(b) + } + return b +} + +// SrcName is used to translate any identifier into a Go name. +// Mostly used for fields, but used in a couple other places too (enum items). +func SrcName(p *Protocol, name string) string { + // If it's in the name map, use that translation. + if newn, ok := NameMap[name]; ok { + return newn + } + return splitAndTitle(name) +} + +func TypeSrcName(p *Protocol, typ Type) string { + t := typ.XmlName() + + // If this is a base type, then write the raw Go type. + if baseType, ok := typ.(*Base); ok { + return baseType.SrcName() + } + + // If it's in the type map, use that translation. + if newt, ok := TypeMap[t]; ok { + return newt + } + + // If there's a namespace to this type, just use it and be done. + if colon := strings.Index(t, ":"); colon > -1 { + namespace := t[:colon] + rest := t[colon+1:] + return p.ProtocolFind(namespace).PkgName() + "." + splitAndTitle(rest) + } + + // Since there's no namespace, we're left with the raw type name. + // If the type is part of the source we're generating (i.e., there is + // no parent protocol), then just return that type name. + // Otherwise, we must qualify it with a package name. + if p.Parent == nil { + return splitAndTitle(t) + } + return p.PkgName() + "." + splitAndTitle(t) +} diff --git a/vend/xgb/xgbgen/type.go b/vend/xgb/xgbgen/type.go new file mode 100644 index 0000000..59f1a2d --- /dev/null +++ b/vend/xgb/xgbgen/type.go @@ -0,0 +1,390 @@ +package main + +import ( + "fmt" + "strings" +) + +type Type interface { + Initialize(p *Protocol) + SrcName() string + XmlName() string + Size() Size + + Define(c *Context) +} + +type Types []Type + +func (ts Types) Len() int { return len(ts) } +func (ts Types) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] } +func (ts Types) Less(i, j int) bool { + x1, x2 := ts[i].XmlName(), ts[j].XmlName() + s1, s2 := ts[i].SrcName(), ts[j].SrcName() + return (s1 == s2 && x1 < x2) || s1 < s2 +} + +// Translation is used *only* when transitioning from XML types to +// our better representation. They are placeholders for the real types (below) +// that will replace them. +type Translation struct { + xmlName string +} + +func newTranslation(name string) *Translation { + return &Translation{xmlName: name} +} + +// RealType takes 'XmlName' and finds its real concrete type in our Protocol. +// It is an error if we can't find such a type. +func (t *Translation) RealType(p *Protocol) Type { + // Check to see if there is a namespace. If so, strip it and use it to + // make sure we only look for a type in that protocol. + namespace, typeName := "", t.XmlName() + if ni := strings.Index(t.XmlName(), ":"); ni > -1 { + namespace, typeName = strings.ToLower(typeName[:ni]), typeName[ni+1:] + } + + if len(namespace) == 0 || namespace == strings.ToLower(p.Name) { + for _, typ := range p.Types { + if typeName == typ.XmlName() { + return typ + } + } + } + for _, imp := range p.Imports { + if len(namespace) == 0 || namespace == strings.ToLower(imp.Name) { + for _, typ := range imp.Types { + if typeName == typ.XmlName() { + return typ + } + } + } + } + panic("Could not find real type for translation type: " + t.XmlName()) +} + +func (t *Translation) SrcName() string { + panic("it is illegal to call SrcName on a translation type") +} + +func (t *Translation) XmlName() string { + return t.xmlName +} + +func (t *Translation) Size() Size { + panic("it is illegal to call Size on a translation type") +} + +func (t *Translation) Define(c *Context) { + panic("it is illegal to call Define on a translation type") +} + +func (t *Translation) Initialize(p *Protocol) { + panic("it is illegal to call Initialize on a translation type") +} + +type Base struct { + srcName string + xmlName string + size Size +} + +func (b *Base) SrcName() string { + return b.srcName +} + +func (b *Base) XmlName() string { + return b.xmlName +} + +func (b *Base) Size() Size { + return b.size +} + +func (b *Base) Initialize(p *Protocol) { + b.srcName = TypeSrcName(p, b) +} + +type Enum struct { + srcName string + xmlName string + Items []*EnumItem +} + +type EnumItem struct { + srcName string + xmlName string + Expr Expression +} + +func (enum *Enum) SrcName() string { + return enum.srcName +} + +func (enum *Enum) XmlName() string { + return enum.xmlName +} + +func (enum *Enum) Size() Size { + panic("Cannot take size of enum") +} + +func (enum *Enum) Initialize(p *Protocol) { + enum.srcName = TypeSrcName(p, enum) + for _, item := range enum.Items { + item.srcName = SrcName(p, item.xmlName) + if item.Expr != nil { + item.Expr.Initialize(p) + } + } +} + +type Resource struct { + srcName string + xmlName string +} + +func (r *Resource) SrcName() string { + return r.srcName +} + +func (r *Resource) XmlName() string { + return r.xmlName +} + +func (r *Resource) Size() Size { + return newFixedSize(BaseTypeSizes["Id"], true) +} + +func (r *Resource) Initialize(p *Protocol) { + r.srcName = TypeSrcName(p, r) +} + +type TypeDef struct { + srcName string + xmlName string + Old Type +} + +func (t *TypeDef) SrcName() string { + return t.srcName +} + +func (t *TypeDef) XmlName() string { + return t.xmlName +} + +func (t *TypeDef) Size() Size { + return t.Old.Size() +} + +func (t *TypeDef) Initialize(p *Protocol) { + t.Old = t.Old.(*Translation).RealType(p) + t.srcName = TypeSrcName(p, t) +} + +type Event struct { + srcName string + xmlName string + Number int + NoSequence bool + Fields []Field +} + +func (e *Event) SrcName() string { + return e.srcName +} + +func (e *Event) XmlName() string { + return e.xmlName +} + +func (e *Event) Size() Size { + return newExpressionSize(&Value{v: 32}, true) +} + +func (e *Event) Initialize(p *Protocol) { + e.srcName = TypeSrcName(p, e) + for _, field := range e.Fields { + field.Initialize(p) + } +} + +func (e *Event) EvType() string { + return fmt.Sprintf("%sEvent", e.srcName) +} + +type EventCopy struct { + srcName string + xmlName string + Old Type + Number int +} + +func (e *EventCopy) SrcName() string { + return e.srcName +} + +func (e *EventCopy) XmlName() string { + return e.xmlName +} + +func (e *EventCopy) Size() Size { + return newExpressionSize(&Value{v: 32}, true) +} + +func (e *EventCopy) Initialize(p *Protocol) { + e.srcName = TypeSrcName(p, e) + e.Old = e.Old.(*Translation).RealType(p) + if _, ok := e.Old.(*Event); !ok { + panic("an EventCopy's old type *must* be *Event") + } +} + +func (e *EventCopy) EvType() string { + return fmt.Sprintf("%sEvent", e.srcName) +} + +type Error struct { + srcName string + xmlName string + Number int + Fields []Field +} + +func (e *Error) SrcName() string { + return e.srcName +} + +func (e *Error) XmlName() string { + return e.xmlName +} + +func (e *Error) Size() Size { + return newExpressionSize(&Value{v: 32}, true) +} + +func (e *Error) Initialize(p *Protocol) { + e.srcName = TypeSrcName(p, e) + for _, field := range e.Fields { + field.Initialize(p) + } +} + +func (e *Error) ErrConst() string { + return fmt.Sprintf("Bad%s", e.srcName) +} + +func (e *Error) ErrType() string { + return fmt.Sprintf("%sError", e.srcName) +} + +type ErrorCopy struct { + srcName string + xmlName string + Old Type + Number int +} + +func (e *ErrorCopy) SrcName() string { + return e.srcName +} + +func (e *ErrorCopy) XmlName() string { + return e.xmlName +} + +func (e *ErrorCopy) Size() Size { + return newExpressionSize(&Value{v: 32}, true) +} + +func (e *ErrorCopy) Initialize(p *Protocol) { + e.srcName = TypeSrcName(p, e) + e.Old = e.Old.(*Translation).RealType(p) + if _, ok := e.Old.(*Error); !ok { + panic("an ErrorCopy's old type *must* be *Event") + } +} + +func (e *ErrorCopy) ErrConst() string { + return fmt.Sprintf("Bad%s", e.srcName) +} + +func (e *ErrorCopy) ErrType() string { + return fmt.Sprintf("%sError", e.srcName) +} + +type Struct struct { + srcName string + xmlName string + Fields []Field +} + +func (s *Struct) SrcName() string { + return s.srcName +} + +func (s *Struct) XmlName() string { + return s.xmlName +} + +func (s *Struct) Size() Size { + size := newFixedSize(0, true) + for _, field := range s.Fields { + size = size.Add(field.Size()) + } + return size +} + +func (s *Struct) Initialize(p *Protocol) { + s.srcName = TypeSrcName(p, s) + for _, field := range s.Fields { + field.Initialize(p) + } +} + +// HasList returns whether there is a field in this struct that is a list. +// When true, a more involved calculation is necessary to compute this struct's +// size. +func (s *Struct) HasList() bool { + for _, field := range s.Fields { + if _, ok := field.(*ListField); ok { + return true + } + } + return false +} + +type Union struct { + srcName string + xmlName string + Fields []Field +} + +func (u *Union) SrcName() string { + return u.srcName +} + +func (u *Union) XmlName() string { + return u.xmlName +} + +// Size for Union is broken. At least, it's broken for XKB. +// It *looks* like the protocol inherently relies on some amount of +// memory unsafety, since some members of unions in XKB are *variable* in +// length! The only thing I can come up with, maybe, is when a union has +// variable size, simply return the raw bytes. Then it's up to the user to +// pass those raw bytes into the appropriate New* constructor. GROSS! +// As of now, just pluck out the first field and return that size. This +// should work for union elements in randr.xml and xproto.xml. +func (u *Union) Size() Size { + return u.Fields[0].Size() +} + +func (u *Union) Initialize(p *Protocol) { + u.srcName = fmt.Sprintf("%sUnion", TypeSrcName(p, u)) + for _, field := range u.Fields { + field.Initialize(p) + } +} diff --git a/vend/xgb/xgbgen/xml.go b/vend/xgb/xgbgen/xml.go new file mode 100644 index 0000000..440d0a8 --- /dev/null +++ b/vend/xgb/xgbgen/xml.go @@ -0,0 +1,138 @@ +package main + +import ( + "encoding/xml" + "io/ioutil" + "log" +) + +type XML struct { + // Root 'xcb' element properties. + XMLName xml.Name `xml:"xcb"` + Header string `xml:"header,attr"` + ExtensionXName string `xml:"extension-xname,attr"` + ExtensionName string `xml:"extension-name,attr"` + MajorVersion string `xml:"major-version,attr"` + MinorVersion string `xml:"minor-version,attr"` + + // Types for all top-level elements. + // First are the simple ones. + Imports XMLImports `xml:"import"` + Enums []*XMLEnum `xml:"enum"` + Xids []*XMLXid `xml:"xidtype"` + XidUnions []*XMLXid `xml:"xidunion"` + TypeDefs []*XMLTypeDef `xml:"typedef"` + EventCopies []*XMLEventCopy `xml:"eventcopy"` + ErrorCopies []*XMLErrorCopy `xml:"errorcopy"` + + // Here are the complex ones, i.e., anything with "structure contents" + Structs []*XMLStruct `xml:"struct"` + Unions []*XMLUnion `xml:"union"` + Requests []*XMLRequest `xml:"request"` + Events []*XMLEvent `xml:"event"` + Errors []*XMLError `xml:"error"` +} + +type XMLImports []*XMLImport + +func (imports XMLImports) Eval() { + for _, imp := range imports { + xmlBytes, err := ioutil.ReadFile(*protoPath + "/" + imp.Name + ".xml") + if err != nil { + log.Fatalf("Could not read X protocol description for import "+ + "'%s' because: %s", imp.Name, err) + } + + imp.xml = &XML{} + err = xml.Unmarshal(xmlBytes, imp.xml) + if err != nil { + log.Fatal("Could not parse X protocol description for import "+ + "'%s' because: %s", imp.Name, err) + } + + // recursive imports... + imp.xml.Imports.Eval() + } +} + +type XMLImport struct { + Name string `xml:",chardata"` + xml *XML `xml:"-"` +} + +type XMLEnum struct { + Name string `xml:"name,attr"` + Items []*XMLEnumItem `xml:"item"` +} + +type XMLEnumItem struct { + Name string `xml:"name,attr"` + Expr *XMLExpression `xml:",any"` +} + +type XMLXid struct { + XMLName xml.Name + Name string `xml:"name,attr"` +} + +type XMLTypeDef struct { + Old string `xml:"oldname,attr"` + New string `xml:"newname,attr"` +} + +type XMLEventCopy struct { + Name string `xml:"name,attr"` + Number int `xml:"number,attr"` + Ref string `xml:"ref,attr"` +} + +type XMLErrorCopy struct { + Name string `xml:"name,attr"` + Number int `xml:"number,attr"` + Ref string `xml:"ref,attr"` +} + +type XMLStruct struct { + Name string `xml:"name,attr"` + Fields []*XMLField `xml:",any"` +} + +type XMLUnion struct { + Name string `xml:"name,attr"` + Fields []*XMLField `xml:",any"` +} + +type XMLRequest struct { + Name string `xml:"name,attr"` + Opcode int `xml:"opcode,attr"` + Combine bool `xml:"combine-adjacent,attr"` + Fields []*XMLField `xml:",any"` + Reply *XMLReply `xml:"reply"` +} + +type XMLReply struct { + Fields []*XMLField `xml:",any"` +} + +type XMLEvent struct { + Name string `xml:"name,attr"` + Number int `xml:"number,attr"` + NoSequence bool `xml:"no-sequence-number,attr"` + Fields []*XMLField `xml:",any"` +} + +type XMLError struct { + Name string `xml:"name,attr"` + Number int `xml:"number,attr"` + Fields []*XMLField `xml:",any"` +} + +type XMLExpression struct { + XMLName xml.Name + + Exprs []*XMLExpression `xml:",any"` + + Data string `xml:",chardata"` + Op string `xml:"op,attr"` + Ref string `xml:"ref,attr"` +} diff --git a/vend/xgb/xgbgen/xml_fields.go b/vend/xgb/xgbgen/xml_fields.go new file mode 100644 index 0000000..8b7b5c7 --- /dev/null +++ b/vend/xgb/xgbgen/xml_fields.go @@ -0,0 +1,86 @@ +package main + +import ( + "encoding/xml" + "log" +) + +type XMLField struct { + XMLName xml.Name + + // For 'pad' element + Bytes uint `xml:"bytes,attr"` + Align uint16 `xml:"align,attr"` + + // For 'field', 'list', 'localfield', 'exprfield' and 'switch' elements. + Name string `xml:"name,attr"` + + // For 'field', 'list', 'localfield', and 'exprfield' elements. + Type string `xml:"type,attr"` + + // For 'list', 'exprfield' and 'switch' elements. + Expr *XMLExpression `xml:",any"` + + // For 'valueparm' element. + ValueMaskType string `xml:"value-mask-type,attr"` + ValueMaskName string `xml:"value-mask-name,attr"` + ValueListName string `xml:"value-list-name,attr"` + + // For 'switch' element. + Bitcases []*XMLBitcase `xml:"bitcase"` + + // I don't know which elements these are for. The documentation is vague. + // They also seem to be completely optional. + OptEnum string `xml:"enum,attr"` + OptMask string `xml:"mask,attr"` + OptAltEnum string `xml:"altenum,attr"` +} + +// Bitcase represents a single expression followed by any number of fields. +// Namely, if the switch's expression (all bitcases are inside a switch), +// and'd with the bitcase's expression is equal to the bitcase expression, +// then the fields should be included in its parent structure. +// Note that since a bitcase is unique in that expressions and fields are +// siblings, we must exhaustively search for one of them. Essentially, +// it's the closest thing to a Union I can get to in Go without interfaces. +// Would an '' tag have been too much to ask? :-( +type XMLBitcase struct { + Fields []*XMLField `xml:",any"` + + // All the different expressions. + // When it comes time to choose one, use the 'Expr' method. + ExprOp *XMLExpression `xml:"op"` + ExprUnOp *XMLExpression `xml:"unop"` + ExprField *XMLExpression `xml:"fieldref"` + ExprValue *XMLExpression `xml:"value"` + ExprBit *XMLExpression `xml:"bit"` + ExprEnum *XMLExpression `xml:"enumref"` + ExprSum *XMLExpression `xml:"sumof"` + ExprPop *XMLExpression `xml:"popcount"` +} + +// Expr chooses the only non-nil Expr* field from Bitcase. +// Panic if there is more than one non-nil expression. +func (b *XMLBitcase) Expr() *XMLExpression { + choices := []*XMLExpression{ + b.ExprOp, b.ExprUnOp, b.ExprField, b.ExprValue, + b.ExprBit, b.ExprEnum, b.ExprSum, b.ExprPop, + } + + var choice *XMLExpression = nil + numNonNil := 0 + for _, c := range choices { + if c != nil { + numNonNil++ + choice = c + } + } + + if choice == nil { + log.Panicf("No top level expression found in a bitcase.") + } + if numNonNil > 1 { + log.Panicf("More than one top-level expression was found in a bitcase.") + } + return choice +} diff --git a/vend/xgb/xinerama/xinerama.go b/vend/xgb/xinerama/xinerama.go new file mode 100644 index 0000000..580387c --- /dev/null +++ b/vend/xgb/xinerama/xinerama.go @@ -0,0 +1,718 @@ +// Package xinerama is the X client API for the XINERAMA extension. +package xinerama + +// This file is automatically generated from xinerama.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XINERAMA extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 8, "XINERAMA").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XINERAMA could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XINERAMA"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XINERAMA"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XINERAMA"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XINERAMA"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XINERAMA"] = make(map[int]xgb.NewErrorFun) +} + +type ScreenInfo struct { + XOrg int16 + YOrg int16 + Width uint16 + Height uint16 +} + +// ScreenInfoRead reads a byte slice into a ScreenInfo value. +func ScreenInfoRead(buf []byte, v *ScreenInfo) int { + b := 0 + + v.XOrg = int16(xgb.Get16(buf[b:])) + b += 2 + + v.YOrg = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// ScreenInfoReadList reads a byte slice into a list of ScreenInfo values. +func ScreenInfoReadList(buf []byte, dest []ScreenInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ScreenInfo{} + b += ScreenInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ScreenInfo value to a byte slice. +func (v ScreenInfo) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], uint16(v.XOrg)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.YOrg)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + return buf[:b] +} + +// ScreenInfoListBytes writes a list of ScreenInfo values to a byte slice. +func ScreenInfoListBytes(buf []byte, list []ScreenInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// GetScreenCountCookie is a cookie used only for GetScreenCount requests. +type GetScreenCountCookie struct { + *xgb.Cookie +} + +// GetScreenCount sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenCountCookie.Reply() +func GetScreenCount(c *xgb.Conn, Window xproto.Window) GetScreenCountCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'GetScreenCount' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenCountRequest(c, Window), cookie) + return GetScreenCountCookie{cookie} +} + +// GetScreenCountUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenCountUnchecked(c *xgb.Conn, Window xproto.Window) GetScreenCountCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'GetScreenCount' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenCountRequest(c, Window), cookie) + return GetScreenCountCookie{cookie} +} + +// GetScreenCountReply represents the data returned from a GetScreenCount request. +type GetScreenCountReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + ScreenCount byte + Window xproto.Window +} + +// Reply blocks and returns the reply data for a GetScreenCount request. +func (cook GetScreenCountCookie) Reply() (*GetScreenCountReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenCountReply(buf), nil +} + +// getScreenCountReply reads a byte slice into a GetScreenCountReply value. +func getScreenCountReply(buf []byte) *GetScreenCountReply { + v := new(GetScreenCountReply) + b := 1 // skip reply determinant + + v.ScreenCount = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetScreenCount +// getScreenCountRequest writes a GetScreenCount request to a byte slice. +func getScreenCountRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XINERAMA"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetScreenSizeCookie is a cookie used only for GetScreenSize requests. +type GetScreenSizeCookie struct { + *xgb.Cookie +} + +// GetScreenSize sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenSizeCookie.Reply() +func GetScreenSize(c *xgb.Conn, Window xproto.Window, Screen uint32) GetScreenSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'GetScreenSize' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenSizeRequest(c, Window, Screen), cookie) + return GetScreenSizeCookie{cookie} +} + +// GetScreenSizeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenSizeUnchecked(c *xgb.Conn, Window xproto.Window, Screen uint32) GetScreenSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'GetScreenSize' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenSizeRequest(c, Window, Screen), cookie) + return GetScreenSizeCookie{cookie} +} + +// GetScreenSizeReply represents the data returned from a GetScreenSize request. +type GetScreenSizeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint32 + Height uint32 + Window xproto.Window + Screen uint32 +} + +// Reply blocks and returns the reply data for a GetScreenSize request. +func (cook GetScreenSizeCookie) Reply() (*GetScreenSizeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenSizeReply(buf), nil +} + +// getScreenSizeReply reads a byte slice into a GetScreenSizeReply value. +func getScreenSizeReply(buf []byte) *GetScreenSizeReply { + v := new(GetScreenSizeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Width = xgb.Get32(buf[b:]) + b += 4 + + v.Height = xgb.Get32(buf[b:]) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Screen = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetScreenSize +// getScreenSizeRequest writes a GetScreenSize request to a byte slice. +func getScreenSizeRequest(c *xgb.Conn, Window xproto.Window, Screen uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XINERAMA"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], Screen) + b += 4 + + return buf +} + +// GetStateCookie is a cookie used only for GetState requests. +type GetStateCookie struct { + *xgb.Cookie +} + +// GetState sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetStateCookie.Reply() +func GetState(c *xgb.Conn, Window xproto.Window) GetStateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'GetState' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getStateRequest(c, Window), cookie) + return GetStateCookie{cookie} +} + +// GetStateUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetStateUnchecked(c *xgb.Conn, Window xproto.Window) GetStateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'GetState' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getStateRequest(c, Window), cookie) + return GetStateCookie{cookie} +} + +// GetStateReply represents the data returned from a GetState request. +type GetStateReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + State byte + Window xproto.Window +} + +// Reply blocks and returns the reply data for a GetState request. +func (cook GetStateCookie) Reply() (*GetStateReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getStateReply(buf), nil +} + +// getStateReply reads a byte slice into a GetStateReply value. +func getStateReply(buf []byte) *GetStateReply { + v := new(GetStateReply) + b := 1 // skip reply determinant + + v.State = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetState +// getStateRequest writes a GetState request to a byte slice. +func getStateRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XINERAMA"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// IsActiveCookie is a cookie used only for IsActive requests. +type IsActiveCookie struct { + *xgb.Cookie +} + +// IsActive sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsActiveCookie.Reply() +func IsActive(c *xgb.Conn) IsActiveCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'IsActive' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isActiveRequest(c), cookie) + return IsActiveCookie{cookie} +} + +// IsActiveUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsActiveUnchecked(c *xgb.Conn) IsActiveCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'IsActive' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isActiveRequest(c), cookie) + return IsActiveCookie{cookie} +} + +// IsActiveReply represents the data returned from a IsActive request. +type IsActiveReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + State uint32 +} + +// Reply blocks and returns the reply data for a IsActive request. +func (cook IsActiveCookie) Reply() (*IsActiveReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isActiveReply(buf), nil +} + +// isActiveReply reads a byte slice into a IsActiveReply value. +func isActiveReply(buf []byte) *IsActiveReply { + v := new(IsActiveReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.State = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for IsActive +// isActiveRequest writes a IsActive request to a byte slice. +func isActiveRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XINERAMA"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryScreensCookie is a cookie used only for QueryScreens requests. +type QueryScreensCookie struct { + *xgb.Cookie +} + +// QueryScreens sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryScreensCookie.Reply() +func QueryScreens(c *xgb.Conn) QueryScreensCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'QueryScreens' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryScreensRequest(c), cookie) + return QueryScreensCookie{cookie} +} + +// QueryScreensUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryScreensUnchecked(c *xgb.Conn) QueryScreensCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'QueryScreens' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryScreensRequest(c), cookie) + return QueryScreensCookie{cookie} +} + +// QueryScreensReply represents the data returned from a QueryScreens request. +type QueryScreensReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Number uint32 + // padding: 20 bytes + ScreenInfo []ScreenInfo // size: xgb.Pad((int(Number) * 8)) +} + +// Reply blocks and returns the reply data for a QueryScreens request. +func (cook QueryScreensCookie) Reply() (*QueryScreensReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryScreensReply(buf), nil +} + +// queryScreensReply reads a byte slice into a QueryScreensReply value. +func queryScreensReply(buf []byte) *QueryScreensReply { + v := new(QueryScreensReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Number = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.ScreenInfo = make([]ScreenInfo, v.Number) + b += ScreenInfoReadList(buf[b:], v.ScreenInfo) + + return v +} + +// Write request to wire for QueryScreens +// queryScreensRequest writes a QueryScreens request to a byte slice. +func queryScreensRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XINERAMA"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, Major byte, Minor byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, Major, Minor), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, Major byte, Minor byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XINERAMA"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XINERAMA'. xinerama.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, Major, Minor), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Major uint16 + Minor uint16 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Major = xgb.Get16(buf[b:]) + b += 2 + + v.Minor = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, Major byte, Minor byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XINERAMA"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Major + b += 1 + + buf[b] = Minor + b += 1 + + return buf +} diff --git a/vend/xgb/xprint/xprint.go b/vend/xgb/xprint/xprint.go new file mode 100644 index 0000000..ee9702d --- /dev/null +++ b/vend/xgb/xprint/xprint.go @@ -0,0 +1,2554 @@ +// Package xprint is the X client API for the XpExtension extension. +package xprint + +// This file is automatically generated from xprint.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XpExtension extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 11, "XpExtension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XpExtension could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XpExtension"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XpExtension"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XpExtension"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XpExtension"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XpExtension"] = make(map[int]xgb.NewErrorFun) +} + +const ( + AttrJobAttr = 1 + AttrDocAttr = 2 + AttrPageAttr = 3 + AttrPrinterAttr = 4 + AttrServerAttr = 5 + AttrMediumAttr = 6 + AttrSpoolerAttr = 7 +) + +// AttributNotify is the event number for a AttributNotifyEvent. +const AttributNotify = 1 + +type AttributNotifyEvent struct { + Sequence uint16 + Detail byte + Context Pcontext +} + +// AttributNotifyEventNew constructs a AttributNotifyEvent value that implements xgb.Event from a byte slice. +func AttributNotifyEventNew(buf []byte) xgb.Event { + v := AttributNotifyEvent{} + b := 1 // don't read event number + + v.Detail = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Context = Pcontext(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a AttributNotifyEvent value to a byte slice. +func (v AttributNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 1 + b += 1 + + buf[b] = v.Detail + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Context)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the AttributNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v AttributNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of AttributNotifyEvent. +func (v AttributNotifyEvent) String() string { + fieldVals := make([]string, 0, 2) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Context: %d", v.Context)) + return "AttributNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["XpExtension"][1] = AttributNotifyEventNew +} + +// BadBadContext is the error number for a BadBadContext. +const BadBadContext = 0 + +type BadContextError struct { + Sequence uint16 + NiceName string +} + +// BadContextErrorNew constructs a BadContextError value that implements xgb.Error from a byte slice. +func BadContextErrorNew(buf []byte) xgb.Error { + v := BadContextError{} + v.NiceName = "BadContext" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadContext error. +// This is mostly used internally. +func (err BadContextError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadContext error. If no bad value exists, 0 is returned. +func (err BadContextError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadContext error. + +func (err BadContextError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadContext {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XpExtension"][0] = BadContextErrorNew +} + +// BadBadSequence is the error number for a BadBadSequence. +const BadBadSequence = 1 + +type BadSequenceError struct { + Sequence uint16 + NiceName string +} + +// BadSequenceErrorNew constructs a BadSequenceError value that implements xgb.Error from a byte slice. +func BadSequenceErrorNew(buf []byte) xgb.Error { + v := BadSequenceError{} + v.NiceName = "BadSequence" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadSequence error. +// This is mostly used internally. +func (err BadSequenceError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadSequence error. If no bad value exists, 0 is returned. +func (err BadSequenceError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadSequence error. + +func (err BadSequenceError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadSequence {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XpExtension"][1] = BadSequenceErrorNew +} + +const ( + DetailStartJobNotify = 1 + DetailEndJobNotify = 2 + DetailStartDocNotify = 3 + DetailEndDocNotify = 4 + DetailStartPageNotify = 5 + DetailEndPageNotify = 6 +) + +const ( + EvMaskNoEventMask = 0 + EvMaskPrintMask = 1 + EvMaskAttributeMask = 2 +) + +const ( + GetDocFinished = 0 + GetDocSecondConsumer = 1 +) + +// Notify is the event number for a NotifyEvent. +const Notify = 0 + +type NotifyEvent struct { + Sequence uint16 + Detail byte + Context Pcontext + Cancel bool +} + +// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice. +func NotifyEventNew(buf []byte) xgb.Event { + v := NotifyEvent{} + b := 1 // don't read event number + + v.Detail = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Context = Pcontext(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.Cancel = true + } else { + v.Cancel = false + } + b += 1 + + return v +} + +// Bytes writes a NotifyEvent value to a byte slice. +func (v NotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = v.Detail + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Context)) + b += 4 + + if v.Cancel { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// SequenceId returns the sequence id attached to the Notify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v NotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of NotifyEvent. +func (v NotifyEvent) String() string { + fieldVals := make([]string, 0, 3) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Context: %d", v.Context)) + fieldVals = append(fieldVals, xgb.Sprintf("Cancel: %t", v.Cancel)) + return "Notify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["XpExtension"][0] = NotifyEventNew +} + +type Pcontext uint32 + +func NewPcontextId(c *xgb.Conn) (Pcontext, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Pcontext(id), nil +} + +type Printer struct { + NameLen uint32 + Name []String8 // size: xgb.Pad((int(NameLen) * 1)) + // alignment gap to multiple of 4 + DescLen uint32 + Description []String8 // size: xgb.Pad((int(DescLen) * 1)) + // alignment gap to multiple of 4 +} + +// PrinterRead reads a byte slice into a Printer value. +func PrinterRead(buf []byte, v *Printer) int { + b := 0 + + v.NameLen = xgb.Get32(buf[b:]) + b += 4 + + v.Name = make([]String8, v.NameLen) + for i := 0; i < int(v.NameLen); i++ { + v.Name[i] = String8(buf[b]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + v.DescLen = xgb.Get32(buf[b:]) + b += 4 + + v.Description = make([]String8, v.DescLen) + for i := 0; i < int(v.DescLen); i++ { + v.Description[i] = String8(buf[b]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + return b +} + +// PrinterReadList reads a byte slice into a list of Printer values. +func PrinterReadList(buf []byte, dest []Printer) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Printer{} + b += PrinterRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Printer value to a byte slice. +func (v Printer) Bytes() []byte { + buf := make([]byte, (((((4 + xgb.Pad((int(v.NameLen) * 1))) + 4) + 4) + xgb.Pad((int(v.DescLen) * 1))) + 4)) + b := 0 + + xgb.Put32(buf[b:], v.NameLen) + b += 4 + + for i := 0; i < int(v.NameLen); i++ { + buf[b] = byte(v.Name[i]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + xgb.Put32(buf[b:], v.DescLen) + b += 4 + + for i := 0; i < int(v.DescLen); i++ { + buf[b] = byte(v.Description[i]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + return buf[:b] +} + +// PrinterListBytes writes a list of Printer values to a byte slice. +func PrinterListBytes(buf []byte, list []Printer) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// PrinterListSize computes the size (bytes) of a list of Printer values. +func PrinterListSize(list []Printer) int { + size := 0 + for _, item := range list { + size += (((((4 + xgb.Pad((int(item.NameLen) * 1))) + 4) + 4) + xgb.Pad((int(item.DescLen) * 1))) + 4) + } + return size +} + +type String8 byte + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CreateContextCookie is a cookie used only for CreateContext requests. +type CreateContextCookie struct { + *xgb.Cookie +} + +// CreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateContext(c *xgb.Conn, ContextId uint32, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createContextRequest(c, ContextId, PrinterNameLen, LocaleLen, PrinterName, Locale), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateContextCookie.Check() +func CreateContextChecked(c *xgb.Conn, ContextId uint32, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createContextRequest(c, ContextId, PrinterNameLen, LocaleLen, PrinterName, Locale), cookie) + return CreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateContext +// createContextRequest writes a CreateContext request to a byte slice. +func createContextRequest(c *xgb.Conn, ContextId uint32, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) []byte { + size := xgb.Pad((((16 + xgb.Pad((int(PrinterNameLen) * 1))) + 4) + xgb.Pad((int(LocaleLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], ContextId) + b += 4 + + xgb.Put32(buf[b:], PrinterNameLen) + b += 4 + + xgb.Put32(buf[b:], LocaleLen) + b += 4 + + for i := 0; i < int(PrinterNameLen); i++ { + buf[b] = byte(PrinterName[i]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(LocaleLen); i++ { + buf[b] = byte(Locale[i]) + b += 1 + } + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// PrintDestroyContextCookie is a cookie used only for PrintDestroyContext requests. +type PrintDestroyContextCookie struct { + *xgb.Cookie +} + +// PrintDestroyContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintDestroyContext(c *xgb.Conn, Context uint32) PrintDestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintDestroyContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printDestroyContextRequest(c, Context), cookie) + return PrintDestroyContextCookie{cookie} +} + +// PrintDestroyContextChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintDestroyContextCookie.Check() +func PrintDestroyContextChecked(c *xgb.Conn, Context uint32) PrintDestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintDestroyContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printDestroyContextRequest(c, Context), cookie) + return PrintDestroyContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintDestroyContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintDestroyContext +// printDestroyContextRequest writes a PrintDestroyContext request to a byte slice. +func printDestroyContextRequest(c *xgb.Conn, Context uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Context) + b += 4 + + return buf +} + +// PrintEndDocCookie is a cookie used only for PrintEndDoc requests. +type PrintEndDocCookie struct { + *xgb.Cookie +} + +// PrintEndDoc sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintEndDoc(c *xgb.Conn, Cancel bool) PrintEndDocCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintEndDoc' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printEndDocRequest(c, Cancel), cookie) + return PrintEndDocCookie{cookie} +} + +// PrintEndDocChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintEndDocCookie.Check() +func PrintEndDocChecked(c *xgb.Conn, Cancel bool) PrintEndDocCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintEndDoc' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printEndDocRequest(c, Cancel), cookie) + return PrintEndDocCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintEndDocCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintEndDoc +// printEndDocRequest writes a PrintEndDoc request to a byte slice. +func printEndDocRequest(c *xgb.Conn, Cancel bool) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + if Cancel { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// PrintEndJobCookie is a cookie used only for PrintEndJob requests. +type PrintEndJobCookie struct { + *xgb.Cookie +} + +// PrintEndJob sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintEndJob(c *xgb.Conn, Cancel bool) PrintEndJobCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintEndJob' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printEndJobRequest(c, Cancel), cookie) + return PrintEndJobCookie{cookie} +} + +// PrintEndJobChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintEndJobCookie.Check() +func PrintEndJobChecked(c *xgb.Conn, Cancel bool) PrintEndJobCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintEndJob' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printEndJobRequest(c, Cancel), cookie) + return PrintEndJobCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintEndJobCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintEndJob +// printEndJobRequest writes a PrintEndJob request to a byte slice. +func printEndJobRequest(c *xgb.Conn, Cancel bool) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + if Cancel { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// PrintEndPageCookie is a cookie used only for PrintEndPage requests. +type PrintEndPageCookie struct { + *xgb.Cookie +} + +// PrintEndPage sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintEndPage(c *xgb.Conn, Cancel bool) PrintEndPageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintEndPage' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printEndPageRequest(c, Cancel), cookie) + return PrintEndPageCookie{cookie} +} + +// PrintEndPageChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintEndPageCookie.Check() +func PrintEndPageChecked(c *xgb.Conn, Cancel bool) PrintEndPageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintEndPage' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printEndPageRequest(c, Cancel), cookie) + return PrintEndPageCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintEndPageCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintEndPage +// printEndPageRequest writes a PrintEndPage request to a byte slice. +func printEndPageRequest(c *xgb.Conn, Cancel bool) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + if Cancel { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// PrintGetAttributesCookie is a cookie used only for PrintGetAttributes requests. +type PrintGetAttributesCookie struct { + *xgb.Cookie +} + +// PrintGetAttributes sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetAttributesCookie.Reply() +func PrintGetAttributes(c *xgb.Conn, Context Pcontext, Pool byte) PrintGetAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetAttributes' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetAttributesRequest(c, Context, Pool), cookie) + return PrintGetAttributesCookie{cookie} +} + +// PrintGetAttributesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetAttributesUnchecked(c *xgb.Conn, Context Pcontext, Pool byte) PrintGetAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetAttributes' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetAttributesRequest(c, Context, Pool), cookie) + return PrintGetAttributesCookie{cookie} +} + +// PrintGetAttributesReply represents the data returned from a PrintGetAttributes request. +type PrintGetAttributesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + StringLen uint32 + // padding: 20 bytes + Attributes []String8 // size: xgb.Pad((int(StringLen) * 1)) +} + +// Reply blocks and returns the reply data for a PrintGetAttributes request. +func (cook PrintGetAttributesCookie) Reply() (*PrintGetAttributesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetAttributesReply(buf), nil +} + +// printGetAttributesReply reads a byte slice into a PrintGetAttributesReply value. +func printGetAttributesReply(buf []byte) *PrintGetAttributesReply { + v := new(PrintGetAttributesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.StringLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Attributes = make([]String8, v.StringLen) + for i := 0; i < int(v.StringLen); i++ { + v.Attributes[i] = String8(buf[b]) + b += 1 + } + + return v +} + +// Write request to wire for PrintGetAttributes +// printGetAttributesRequest writes a PrintGetAttributes request to a byte slice. +func printGetAttributesRequest(c *xgb.Conn, Context Pcontext, Pool byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + buf[b] = Pool + b += 1 + + b += 3 // padding + + return buf +} + +// PrintGetContextCookie is a cookie used only for PrintGetContext requests. +type PrintGetContextCookie struct { + *xgb.Cookie +} + +// PrintGetContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetContextCookie.Reply() +func PrintGetContext(c *xgb.Conn) PrintGetContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetContextRequest(c), cookie) + return PrintGetContextCookie{cookie} +} + +// PrintGetContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetContextUnchecked(c *xgb.Conn) PrintGetContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetContextRequest(c), cookie) + return PrintGetContextCookie{cookie} +} + +// PrintGetContextReply represents the data returned from a PrintGetContext request. +type PrintGetContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Context uint32 +} + +// Reply blocks and returns the reply data for a PrintGetContext request. +func (cook PrintGetContextCookie) Reply() (*PrintGetContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetContextReply(buf), nil +} + +// printGetContextReply reads a byte slice into a PrintGetContextReply value. +func printGetContextReply(buf []byte) *PrintGetContextReply { + v := new(PrintGetContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Context = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for PrintGetContext +// printGetContextRequest writes a PrintGetContext request to a byte slice. +func printGetContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// PrintGetDocumentDataCookie is a cookie used only for PrintGetDocumentData requests. +type PrintGetDocumentDataCookie struct { + *xgb.Cookie +} + +// PrintGetDocumentData sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetDocumentDataCookie.Reply() +func PrintGetDocumentData(c *xgb.Conn, Context Pcontext, MaxBytes uint32) PrintGetDocumentDataCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetDocumentData' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetDocumentDataRequest(c, Context, MaxBytes), cookie) + return PrintGetDocumentDataCookie{cookie} +} + +// PrintGetDocumentDataUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetDocumentDataUnchecked(c *xgb.Conn, Context Pcontext, MaxBytes uint32) PrintGetDocumentDataCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetDocumentData' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetDocumentDataRequest(c, Context, MaxBytes), cookie) + return PrintGetDocumentDataCookie{cookie} +} + +// PrintGetDocumentDataReply represents the data returned from a PrintGetDocumentData request. +type PrintGetDocumentDataReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + StatusCode uint32 + FinishedFlag uint32 + DataLen uint32 + // padding: 12 bytes + Data []byte // size: xgb.Pad((int(DataLen) * 1)) +} + +// Reply blocks and returns the reply data for a PrintGetDocumentData request. +func (cook PrintGetDocumentDataCookie) Reply() (*PrintGetDocumentDataReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetDocumentDataReply(buf), nil +} + +// printGetDocumentDataReply reads a byte slice into a PrintGetDocumentDataReply value. +func printGetDocumentDataReply(buf []byte) *PrintGetDocumentDataReply { + v := new(PrintGetDocumentDataReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.StatusCode = xgb.Get32(buf[b:]) + b += 4 + + v.FinishedFlag = xgb.Get32(buf[b:]) + b += 4 + + v.DataLen = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Data = make([]byte, v.DataLen) + copy(v.Data[:v.DataLen], buf[b:]) + b += int(v.DataLen) + + return v +} + +// Write request to wire for PrintGetDocumentData +// printGetDocumentDataRequest writes a PrintGetDocumentData request to a byte slice. +func printGetDocumentDataRequest(c *xgb.Conn, Context Pcontext, MaxBytes uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], MaxBytes) + b += 4 + + return buf +} + +// PrintGetImageResolutionCookie is a cookie used only for PrintGetImageResolution requests. +type PrintGetImageResolutionCookie struct { + *xgb.Cookie +} + +// PrintGetImageResolution sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetImageResolutionCookie.Reply() +func PrintGetImageResolution(c *xgb.Conn, Context Pcontext) PrintGetImageResolutionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetImageResolution' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetImageResolutionRequest(c, Context), cookie) + return PrintGetImageResolutionCookie{cookie} +} + +// PrintGetImageResolutionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetImageResolutionUnchecked(c *xgb.Conn, Context Pcontext) PrintGetImageResolutionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetImageResolution' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetImageResolutionRequest(c, Context), cookie) + return PrintGetImageResolutionCookie{cookie} +} + +// PrintGetImageResolutionReply represents the data returned from a PrintGetImageResolution request. +type PrintGetImageResolutionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ImageResolution uint16 +} + +// Reply blocks and returns the reply data for a PrintGetImageResolution request. +func (cook PrintGetImageResolutionCookie) Reply() (*PrintGetImageResolutionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetImageResolutionReply(buf), nil +} + +// printGetImageResolutionReply reads a byte slice into a PrintGetImageResolutionReply value. +func printGetImageResolutionReply(buf []byte) *PrintGetImageResolutionReply { + v := new(PrintGetImageResolutionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ImageResolution = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for PrintGetImageResolution +// printGetImageResolutionRequest writes a PrintGetImageResolution request to a byte slice. +func printGetImageResolutionRequest(c *xgb.Conn, Context Pcontext) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 24 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// PrintGetOneAttributesCookie is a cookie used only for PrintGetOneAttributes requests. +type PrintGetOneAttributesCookie struct { + *xgb.Cookie +} + +// PrintGetOneAttributes sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetOneAttributesCookie.Reply() +func PrintGetOneAttributes(c *xgb.Conn, Context Pcontext, NameLen uint32, Pool byte, Name []String8) PrintGetOneAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetOneAttributes' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetOneAttributesRequest(c, Context, NameLen, Pool, Name), cookie) + return PrintGetOneAttributesCookie{cookie} +} + +// PrintGetOneAttributesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetOneAttributesUnchecked(c *xgb.Conn, Context Pcontext, NameLen uint32, Pool byte, Name []String8) PrintGetOneAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetOneAttributes' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetOneAttributesRequest(c, Context, NameLen, Pool, Name), cookie) + return PrintGetOneAttributesCookie{cookie} +} + +// PrintGetOneAttributesReply represents the data returned from a PrintGetOneAttributes request. +type PrintGetOneAttributesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ValueLen uint32 + // padding: 20 bytes + Value []String8 // size: xgb.Pad((int(ValueLen) * 1)) +} + +// Reply blocks and returns the reply data for a PrintGetOneAttributes request. +func (cook PrintGetOneAttributesCookie) Reply() (*PrintGetOneAttributesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetOneAttributesReply(buf), nil +} + +// printGetOneAttributesReply reads a byte slice into a PrintGetOneAttributesReply value. +func printGetOneAttributesReply(buf []byte) *PrintGetOneAttributesReply { + v := new(PrintGetOneAttributesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ValueLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Value = make([]String8, v.ValueLen) + for i := 0; i < int(v.ValueLen); i++ { + v.Value[i] = String8(buf[b]) + b += 1 + } + + return v +} + +// Write request to wire for PrintGetOneAttributes +// printGetOneAttributesRequest writes a PrintGetOneAttributes request to a byte slice. +func printGetOneAttributesRequest(c *xgb.Conn, Context Pcontext, NameLen uint32, Pool byte, Name []String8) []byte { + size := xgb.Pad((16 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], NameLen) + b += 4 + + buf[b] = Pool + b += 1 + + b += 3 // padding + + for i := 0; i < int(NameLen); i++ { + buf[b] = byte(Name[i]) + b += 1 + } + + return buf +} + +// PrintGetPageDimensionsCookie is a cookie used only for PrintGetPageDimensions requests. +type PrintGetPageDimensionsCookie struct { + *xgb.Cookie +} + +// PrintGetPageDimensions sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetPageDimensionsCookie.Reply() +func PrintGetPageDimensions(c *xgb.Conn, Context Pcontext) PrintGetPageDimensionsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetPageDimensions' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetPageDimensionsRequest(c, Context), cookie) + return PrintGetPageDimensionsCookie{cookie} +} + +// PrintGetPageDimensionsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetPageDimensionsUnchecked(c *xgb.Conn, Context Pcontext) PrintGetPageDimensionsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetPageDimensions' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetPageDimensionsRequest(c, Context), cookie) + return PrintGetPageDimensionsCookie{cookie} +} + +// PrintGetPageDimensionsReply represents the data returned from a PrintGetPageDimensions request. +type PrintGetPageDimensionsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint16 + Height uint16 + OffsetX uint16 + OffsetY uint16 + ReproducibleWidth uint16 + ReproducibleHeight uint16 +} + +// Reply blocks and returns the reply data for a PrintGetPageDimensions request. +func (cook PrintGetPageDimensionsCookie) Reply() (*PrintGetPageDimensionsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetPageDimensionsReply(buf), nil +} + +// printGetPageDimensionsReply reads a byte slice into a PrintGetPageDimensionsReply value. +func printGetPageDimensionsReply(buf []byte) *PrintGetPageDimensionsReply { + v := new(PrintGetPageDimensionsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.OffsetX = xgb.Get16(buf[b:]) + b += 2 + + v.OffsetY = xgb.Get16(buf[b:]) + b += 2 + + v.ReproducibleWidth = xgb.Get16(buf[b:]) + b += 2 + + v.ReproducibleHeight = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for PrintGetPageDimensions +// printGetPageDimensionsRequest writes a PrintGetPageDimensions request to a byte slice. +func printGetPageDimensionsRequest(c *xgb.Conn, Context Pcontext) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 21 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// PrintGetPrinterListCookie is a cookie used only for PrintGetPrinterList requests. +type PrintGetPrinterListCookie struct { + *xgb.Cookie +} + +// PrintGetPrinterList sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetPrinterListCookie.Reply() +func PrintGetPrinterList(c *xgb.Conn, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) PrintGetPrinterListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetPrinterList' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetPrinterListRequest(c, PrinterNameLen, LocaleLen, PrinterName, Locale), cookie) + return PrintGetPrinterListCookie{cookie} +} + +// PrintGetPrinterListUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetPrinterListUnchecked(c *xgb.Conn, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) PrintGetPrinterListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetPrinterList' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetPrinterListRequest(c, PrinterNameLen, LocaleLen, PrinterName, Locale), cookie) + return PrintGetPrinterListCookie{cookie} +} + +// PrintGetPrinterListReply represents the data returned from a PrintGetPrinterList request. +type PrintGetPrinterListReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ListCount uint32 + // padding: 20 bytes + Printers []Printer // size: PrinterListSize(Printers) +} + +// Reply blocks and returns the reply data for a PrintGetPrinterList request. +func (cook PrintGetPrinterListCookie) Reply() (*PrintGetPrinterListReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetPrinterListReply(buf), nil +} + +// printGetPrinterListReply reads a byte slice into a PrintGetPrinterListReply value. +func printGetPrinterListReply(buf []byte) *PrintGetPrinterListReply { + v := new(PrintGetPrinterListReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ListCount = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Printers = make([]Printer, v.ListCount) + b += PrinterReadList(buf[b:], v.Printers) + + return v +} + +// Write request to wire for PrintGetPrinterList +// printGetPrinterListRequest writes a PrintGetPrinterList request to a byte slice. +func printGetPrinterListRequest(c *xgb.Conn, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) []byte { + size := xgb.Pad((((12 + xgb.Pad((int(PrinterNameLen) * 1))) + 4) + xgb.Pad((int(LocaleLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], PrinterNameLen) + b += 4 + + xgb.Put32(buf[b:], LocaleLen) + b += 4 + + for i := 0; i < int(PrinterNameLen); i++ { + buf[b] = byte(PrinterName[i]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(LocaleLen); i++ { + buf[b] = byte(Locale[i]) + b += 1 + } + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// PrintGetScreenOfContextCookie is a cookie used only for PrintGetScreenOfContext requests. +type PrintGetScreenOfContextCookie struct { + *xgb.Cookie +} + +// PrintGetScreenOfContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintGetScreenOfContextCookie.Reply() +func PrintGetScreenOfContext(c *xgb.Conn) PrintGetScreenOfContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetScreenOfContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printGetScreenOfContextRequest(c), cookie) + return PrintGetScreenOfContextCookie{cookie} +} + +// PrintGetScreenOfContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintGetScreenOfContextUnchecked(c *xgb.Conn) PrintGetScreenOfContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintGetScreenOfContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printGetScreenOfContextRequest(c), cookie) + return PrintGetScreenOfContextCookie{cookie} +} + +// PrintGetScreenOfContextReply represents the data returned from a PrintGetScreenOfContext request. +type PrintGetScreenOfContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Root xproto.Window +} + +// Reply blocks and returns the reply data for a PrintGetScreenOfContext request. +func (cook PrintGetScreenOfContextCookie) Reply() (*PrintGetScreenOfContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printGetScreenOfContextReply(buf), nil +} + +// printGetScreenOfContextReply reads a byte slice into a PrintGetScreenOfContextReply value. +func printGetScreenOfContextReply(buf []byte) *PrintGetScreenOfContextReply { + v := new(PrintGetScreenOfContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Root = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for PrintGetScreenOfContext +// printGetScreenOfContextRequest writes a PrintGetScreenOfContext request to a byte slice. +func printGetScreenOfContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// PrintInputSelectedCookie is a cookie used only for PrintInputSelected requests. +type PrintInputSelectedCookie struct { + *xgb.Cookie +} + +// PrintInputSelected sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintInputSelectedCookie.Reply() +func PrintInputSelected(c *xgb.Conn, Context Pcontext) PrintInputSelectedCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintInputSelected' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printInputSelectedRequest(c, Context), cookie) + return PrintInputSelectedCookie{cookie} +} + +// PrintInputSelectedUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintInputSelectedUnchecked(c *xgb.Conn, Context Pcontext) PrintInputSelectedCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintInputSelected' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printInputSelectedRequest(c, Context), cookie) + return PrintInputSelectedCookie{cookie} +} + +// PrintInputSelectedReply represents the data returned from a PrintInputSelected request. +type PrintInputSelectedReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + EventMask uint32 + AllEventsMask uint32 +} + +// Reply blocks and returns the reply data for a PrintInputSelected request. +func (cook PrintInputSelectedCookie) Reply() (*PrintInputSelectedReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printInputSelectedReply(buf), nil +} + +// printInputSelectedReply reads a byte slice into a PrintInputSelectedReply value. +func printInputSelectedReply(buf []byte) *PrintInputSelectedReply { + v := new(PrintInputSelectedReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.EventMask = xgb.Get32(buf[b:]) + b += 4 + + v.AllEventsMask = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for PrintInputSelected +// printInputSelectedRequest writes a PrintInputSelected request to a byte slice. +func printInputSelectedRequest(c *xgb.Conn, Context Pcontext) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + return buf +} + +// PrintPutDocumentDataCookie is a cookie used only for PrintPutDocumentData requests. +type PrintPutDocumentDataCookie struct { + *xgb.Cookie +} + +// PrintPutDocumentData sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintPutDocumentData(c *xgb.Conn, Drawable xproto.Drawable, LenData uint32, LenFmt uint16, LenOptions uint16, Data []byte, DocFormat []String8, Options []String8) PrintPutDocumentDataCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintPutDocumentData' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printPutDocumentDataRequest(c, Drawable, LenData, LenFmt, LenOptions, Data, DocFormat, Options), cookie) + return PrintPutDocumentDataCookie{cookie} +} + +// PrintPutDocumentDataChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintPutDocumentDataCookie.Check() +func PrintPutDocumentDataChecked(c *xgb.Conn, Drawable xproto.Drawable, LenData uint32, LenFmt uint16, LenOptions uint16, Data []byte, DocFormat []String8, Options []String8) PrintPutDocumentDataCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintPutDocumentData' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printPutDocumentDataRequest(c, Drawable, LenData, LenFmt, LenOptions, Data, DocFormat, Options), cookie) + return PrintPutDocumentDataCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintPutDocumentDataCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintPutDocumentData +// printPutDocumentDataRequest writes a PrintPutDocumentData request to a byte slice. +func printPutDocumentDataRequest(c *xgb.Conn, Drawable xproto.Drawable, LenData uint32, LenFmt uint16, LenOptions uint16, Data []byte, DocFormat []String8, Options []String8) []byte { + size := xgb.Pad((((((16 + xgb.Pad((int(LenData) * 1))) + 4) + xgb.Pad((int(LenFmt) * 1))) + 4) + xgb.Pad((int(LenOptions) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + blen := b + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], LenData) + b += 4 + + xgb.Put16(buf[b:], LenFmt) + b += 2 + + xgb.Put16(buf[b:], LenOptions) + b += 2 + + copy(buf[b:], Data[:LenData]) + b += int(LenData) + + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(LenFmt); i++ { + buf[b] = byte(DocFormat[i]) + b += 1 + } + + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(LenOptions); i++ { + buf[b] = byte(Options[i]) + b += 1 + } + + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] +} + +// PrintQueryScreensCookie is a cookie used only for PrintQueryScreens requests. +type PrintQueryScreensCookie struct { + *xgb.Cookie +} + +// PrintQueryScreens sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintQueryScreensCookie.Reply() +func PrintQueryScreens(c *xgb.Conn) PrintQueryScreensCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintQueryScreens' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printQueryScreensRequest(c), cookie) + return PrintQueryScreensCookie{cookie} +} + +// PrintQueryScreensUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintQueryScreensUnchecked(c *xgb.Conn) PrintQueryScreensCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintQueryScreens' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printQueryScreensRequest(c), cookie) + return PrintQueryScreensCookie{cookie} +} + +// PrintQueryScreensReply represents the data returned from a PrintQueryScreens request. +type PrintQueryScreensReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ListCount uint32 + // padding: 20 bytes + Roots []xproto.Window // size: xgb.Pad((int(ListCount) * 4)) +} + +// Reply blocks and returns the reply data for a PrintQueryScreens request. +func (cook PrintQueryScreensCookie) Reply() (*PrintQueryScreensReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printQueryScreensReply(buf), nil +} + +// printQueryScreensReply reads a byte slice into a PrintQueryScreensReply value. +func printQueryScreensReply(buf []byte) *PrintQueryScreensReply { + v := new(PrintQueryScreensReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ListCount = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Roots = make([]xproto.Window, v.ListCount) + for i := 0; i < int(v.ListCount); i++ { + v.Roots[i] = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for PrintQueryScreens +// printQueryScreensRequest writes a PrintQueryScreens request to a byte slice. +func printQueryScreensRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 22 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// PrintQueryVersionCookie is a cookie used only for PrintQueryVersion requests. +type PrintQueryVersionCookie struct { + *xgb.Cookie +} + +// PrintQueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintQueryVersionCookie.Reply() +func PrintQueryVersion(c *xgb.Conn) PrintQueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintQueryVersion' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printQueryVersionRequest(c), cookie) + return PrintQueryVersionCookie{cookie} +} + +// PrintQueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintQueryVersionUnchecked(c *xgb.Conn) PrintQueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintQueryVersion' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printQueryVersionRequest(c), cookie) + return PrintQueryVersionCookie{cookie} +} + +// PrintQueryVersionReply represents the data returned from a PrintQueryVersion request. +type PrintQueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MajorVersion uint16 + MinorVersion uint16 +} + +// Reply blocks and returns the reply data for a PrintQueryVersion request. +func (cook PrintQueryVersionCookie) Reply() (*PrintQueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printQueryVersionReply(buf), nil +} + +// printQueryVersionReply reads a byte slice into a PrintQueryVersionReply value. +func printQueryVersionReply(buf []byte) *PrintQueryVersionReply { + v := new(PrintQueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for PrintQueryVersion +// printQueryVersionRequest writes a PrintQueryVersion request to a byte slice. +func printQueryVersionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// PrintRehashPrinterListCookie is a cookie used only for PrintRehashPrinterList requests. +type PrintRehashPrinterListCookie struct { + *xgb.Cookie +} + +// PrintRehashPrinterList sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintRehashPrinterList(c *xgb.Conn) PrintRehashPrinterListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintRehashPrinterList' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printRehashPrinterListRequest(c), cookie) + return PrintRehashPrinterListCookie{cookie} +} + +// PrintRehashPrinterListChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintRehashPrinterListCookie.Check() +func PrintRehashPrinterListChecked(c *xgb.Conn) PrintRehashPrinterListCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintRehashPrinterList' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printRehashPrinterListRequest(c), cookie) + return PrintRehashPrinterListCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintRehashPrinterListCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintRehashPrinterList +// printRehashPrinterListRequest writes a PrintRehashPrinterList request to a byte slice. +func printRehashPrinterListRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// PrintSelectInputCookie is a cookie used only for PrintSelectInput requests. +type PrintSelectInputCookie struct { + *xgb.Cookie +} + +// PrintSelectInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintSelectInput(c *xgb.Conn, Context Pcontext, EventMask uint32) PrintSelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSelectInput' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printSelectInputRequest(c, Context, EventMask), cookie) + return PrintSelectInputCookie{cookie} +} + +// PrintSelectInputChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintSelectInputCookie.Check() +func PrintSelectInputChecked(c *xgb.Conn, Context Pcontext, EventMask uint32) PrintSelectInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSelectInput' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printSelectInputRequest(c, Context, EventMask), cookie) + return PrintSelectInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintSelectInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintSelectInput +// printSelectInputRequest writes a PrintSelectInput request to a byte slice. +func printSelectInputRequest(c *xgb.Conn, Context Pcontext, EventMask uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], EventMask) + b += 4 + + return buf +} + +// PrintSetAttributesCookie is a cookie used only for PrintSetAttributes requests. +type PrintSetAttributesCookie struct { + *xgb.Cookie +} + +// PrintSetAttributes sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintSetAttributes(c *xgb.Conn, Context Pcontext, StringLen uint32, Pool byte, Rule byte, Attributes []String8) PrintSetAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSetAttributes' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printSetAttributesRequest(c, Context, StringLen, Pool, Rule, Attributes), cookie) + return PrintSetAttributesCookie{cookie} +} + +// PrintSetAttributesChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintSetAttributesCookie.Check() +func PrintSetAttributesChecked(c *xgb.Conn, Context Pcontext, StringLen uint32, Pool byte, Rule byte, Attributes []String8) PrintSetAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSetAttributes' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printSetAttributesRequest(c, Context, StringLen, Pool, Rule, Attributes), cookie) + return PrintSetAttributesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintSetAttributesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintSetAttributes +// printSetAttributesRequest writes a PrintSetAttributes request to a byte slice. +func printSetAttributesRequest(c *xgb.Conn, Context Pcontext, StringLen uint32, Pool byte, Rule byte, Attributes []String8) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Attributes) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], StringLen) + b += 4 + + buf[b] = Pool + b += 1 + + buf[b] = Rule + b += 1 + + b += 2 // padding + + for i := 0; i < int(len(Attributes)); i++ { + buf[b] = byte(Attributes[i]) + b += 1 + } + + return buf +} + +// PrintSetContextCookie is a cookie used only for PrintSetContext requests. +type PrintSetContextCookie struct { + *xgb.Cookie +} + +// PrintSetContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintSetContext(c *xgb.Conn, Context uint32) PrintSetContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSetContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printSetContextRequest(c, Context), cookie) + return PrintSetContextCookie{cookie} +} + +// PrintSetContextChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintSetContextCookie.Check() +func PrintSetContextChecked(c *xgb.Conn, Context uint32) PrintSetContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSetContext' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printSetContextRequest(c, Context), cookie) + return PrintSetContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintSetContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintSetContext +// printSetContextRequest writes a PrintSetContext request to a byte slice. +func printSetContextRequest(c *xgb.Conn, Context uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Context) + b += 4 + + return buf +} + +// PrintSetImageResolutionCookie is a cookie used only for PrintSetImageResolution requests. +type PrintSetImageResolutionCookie struct { + *xgb.Cookie +} + +// PrintSetImageResolution sends a checked request. +// If an error occurs, it will be returned with the reply by calling PrintSetImageResolutionCookie.Reply() +func PrintSetImageResolution(c *xgb.Conn, Context Pcontext, ImageResolution uint16) PrintSetImageResolutionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSetImageResolution' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(printSetImageResolutionRequest(c, Context, ImageResolution), cookie) + return PrintSetImageResolutionCookie{cookie} +} + +// PrintSetImageResolutionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintSetImageResolutionUnchecked(c *xgb.Conn, Context Pcontext, ImageResolution uint16) PrintSetImageResolutionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintSetImageResolution' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(printSetImageResolutionRequest(c, Context, ImageResolution), cookie) + return PrintSetImageResolutionCookie{cookie} +} + +// PrintSetImageResolutionReply represents the data returned from a PrintSetImageResolution request. +type PrintSetImageResolutionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status bool + PreviousResolutions uint16 +} + +// Reply blocks and returns the reply data for a PrintSetImageResolution request. +func (cook PrintSetImageResolutionCookie) Reply() (*PrintSetImageResolutionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return printSetImageResolutionReply(buf), nil +} + +// printSetImageResolutionReply reads a byte slice into a PrintSetImageResolutionReply value. +func printSetImageResolutionReply(buf []byte) *PrintSetImageResolutionReply { + v := new(PrintSetImageResolutionReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.Status = true + } else { + v.Status = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PreviousResolutions = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for PrintSetImageResolution +// printSetImageResolutionRequest writes a PrintSetImageResolution request to a byte slice. +func printSetImageResolutionRequest(c *xgb.Conn, Context Pcontext, ImageResolution uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 23 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put16(buf[b:], ImageResolution) + b += 2 + + return buf +} + +// PrintStartDocCookie is a cookie used only for PrintStartDoc requests. +type PrintStartDocCookie struct { + *xgb.Cookie +} + +// PrintStartDoc sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintStartDoc(c *xgb.Conn, DriverMode byte) PrintStartDocCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintStartDoc' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printStartDocRequest(c, DriverMode), cookie) + return PrintStartDocCookie{cookie} +} + +// PrintStartDocChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintStartDocCookie.Check() +func PrintStartDocChecked(c *xgb.Conn, DriverMode byte) PrintStartDocCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintStartDoc' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printStartDocRequest(c, DriverMode), cookie) + return PrintStartDocCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintStartDocCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintStartDoc +// printStartDocRequest writes a PrintStartDoc request to a byte slice. +func printStartDocRequest(c *xgb.Conn, DriverMode byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = DriverMode + b += 1 + + return buf +} + +// PrintStartJobCookie is a cookie used only for PrintStartJob requests. +type PrintStartJobCookie struct { + *xgb.Cookie +} + +// PrintStartJob sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintStartJob(c *xgb.Conn, OutputMode byte) PrintStartJobCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintStartJob' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printStartJobRequest(c, OutputMode), cookie) + return PrintStartJobCookie{cookie} +} + +// PrintStartJobChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintStartJobCookie.Check() +func PrintStartJobChecked(c *xgb.Conn, OutputMode byte) PrintStartJobCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintStartJob' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printStartJobRequest(c, OutputMode), cookie) + return PrintStartJobCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintStartJobCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintStartJob +// printStartJobRequest writes a PrintStartJob request to a byte slice. +func printStartJobRequest(c *xgb.Conn, OutputMode byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = OutputMode + b += 1 + + return buf +} + +// PrintStartPageCookie is a cookie used only for PrintStartPage requests. +type PrintStartPageCookie struct { + *xgb.Cookie +} + +// PrintStartPage sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PrintStartPage(c *xgb.Conn, Window xproto.Window) PrintStartPageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintStartPage' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(printStartPageRequest(c, Window), cookie) + return PrintStartPageCookie{cookie} +} + +// PrintStartPageChecked sends a checked request. +// If an error occurs, it can be retrieved using PrintStartPageCookie.Check() +func PrintStartPageChecked(c *xgb.Conn, Window xproto.Window) PrintStartPageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XpExtension"]; !ok { + panic("Cannot issue request 'PrintStartPage' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(printStartPageRequest(c, Window), cookie) + return PrintStartPageCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PrintStartPageCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PrintStartPage +// printStartPageRequest writes a PrintStartPage request to a byte slice. +func printStartPageRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XpExtension"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} diff --git a/vend/xgb/xproto/xproto.go b/vend/xgb/xproto/xproto.go new file mode 100644 index 0000000..ddd3ca9 --- /dev/null +++ b/vend/xgb/xproto/xproto.go @@ -0,0 +1,14934 @@ +// Package xproto is the X client API for the extension. +package xproto + +// This file is automatically generated from xproto.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" +) + +// Setup parses the setup bytes retrieved when +// connecting into a SetupInfo struct. +func Setup(c *xgb.Conn) *SetupInfo { + setup := new(SetupInfo) + SetupInfoRead(c.SetupBytes, setup) + return setup +} + +// DefaultScreen gets the default screen info from SetupInfo. +func (s *SetupInfo) DefaultScreen(c *xgb.Conn) *ScreenInfo { + return &s.Roots[c.DefaultScreen] +} + +// BadAccess is the error number for a BadAccess. +const BadAccess = 10 + +type AccessError RequestError + +// AccessErrorNew constructs a AccessError value that implements xgb.Error from a byte slice. +func AccessErrorNew(buf []byte) xgb.Error { + v := AccessError(RequestErrorNew(buf).(RequestError)) + v.NiceName = "Access" + return v +} + +// SequenceId returns the sequence id attached to the BadAccess error. +// This is mostly used internally. +func (err AccessError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadAccess error. If no bad value exists, 0 is returned. +func (err AccessError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadAccess error. +func (err AccessError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadAccess {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[10] = AccessErrorNew +} + +const ( + AccessControlDisable = 0 + AccessControlEnable = 1 +) + +// BadAlloc is the error number for a BadAlloc. +const BadAlloc = 11 + +type AllocError RequestError + +// AllocErrorNew constructs a AllocError value that implements xgb.Error from a byte slice. +func AllocErrorNew(buf []byte) xgb.Error { + v := AllocError(RequestErrorNew(buf).(RequestError)) + v.NiceName = "Alloc" + return v +} + +// SequenceId returns the sequence id attached to the BadAlloc error. +// This is mostly used internally. +func (err AllocError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadAlloc error. If no bad value exists, 0 is returned. +func (err AllocError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadAlloc error. +func (err AllocError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadAlloc {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[11] = AllocErrorNew +} + +const ( + AllowAsyncPointer = 0 + AllowSyncPointer = 1 + AllowReplayPointer = 2 + AllowAsyncKeyboard = 3 + AllowSyncKeyboard = 4 + AllowReplayKeyboard = 5 + AllowAsyncBoth = 6 + AllowSyncBoth = 7 +) + +type Arc struct { + X int16 + Y int16 + Width uint16 + Height uint16 + Angle1 int16 + Angle2 int16 +} + +// ArcRead reads a byte slice into a Arc value. +func ArcRead(buf []byte, v *Arc) int { + b := 0 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Angle1 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Angle2 = int16(xgb.Get16(buf[b:])) + b += 2 + + return b +} + +// ArcReadList reads a byte slice into a list of Arc values. +func ArcReadList(buf []byte, dest []Arc) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Arc{} + b += ArcRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Arc value to a byte slice. +func (v Arc) Bytes() []byte { + buf := make([]byte, 12) + b := 0 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Angle1)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Angle2)) + b += 2 + + return buf[:b] +} + +// ArcListBytes writes a list of Arc values to a byte slice. +func ArcListBytes(buf []byte, list []Arc) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + ArcModeChord = 0 + ArcModePieSlice = 1 +) + +type Atom uint32 + +func NewAtomId(c *xgb.Conn) (Atom, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Atom(id), nil +} + +const ( + AtomNone = 0 + AtomAny = 0 + AtomPrimary = 1 + AtomSecondary = 2 + AtomArc = 3 + AtomAtom = 4 + AtomBitmap = 5 + AtomCardinal = 6 + AtomColormap = 7 + AtomCursor = 8 + AtomCutBuffer0 = 9 + AtomCutBuffer1 = 10 + AtomCutBuffer2 = 11 + AtomCutBuffer3 = 12 + AtomCutBuffer4 = 13 + AtomCutBuffer5 = 14 + AtomCutBuffer6 = 15 + AtomCutBuffer7 = 16 + AtomDrawable = 17 + AtomFont = 18 + AtomInteger = 19 + AtomPixmap = 20 + AtomPoint = 21 + AtomRectangle = 22 + AtomResourceManager = 23 + AtomRgbColorMap = 24 + AtomRgbBestMap = 25 + AtomRgbBlueMap = 26 + AtomRgbDefaultMap = 27 + AtomRgbGrayMap = 28 + AtomRgbGreenMap = 29 + AtomRgbRedMap = 30 + AtomString = 31 + AtomVisualid = 32 + AtomWindow = 33 + AtomWmCommand = 34 + AtomWmHints = 35 + AtomWmClientMachine = 36 + AtomWmIconName = 37 + AtomWmIconSize = 38 + AtomWmName = 39 + AtomWmNormalHints = 40 + AtomWmSizeHints = 41 + AtomWmZoomHints = 42 + AtomMinSpace = 43 + AtomNormSpace = 44 + AtomMaxSpace = 45 + AtomEndSpace = 46 + AtomSuperscriptX = 47 + AtomSuperscriptY = 48 + AtomSubscriptX = 49 + AtomSubscriptY = 50 + AtomUnderlinePosition = 51 + AtomUnderlineThickness = 52 + AtomStrikeoutAscent = 53 + AtomStrikeoutDescent = 54 + AtomItalicAngle = 55 + AtomXHeight = 56 + AtomQuadWidth = 57 + AtomWeight = 58 + AtomPointSize = 59 + AtomResolution = 60 + AtomCopyright = 61 + AtomNotice = 62 + AtomFontName = 63 + AtomFamilyName = 64 + AtomFullName = 65 + AtomCapHeight = 66 + AtomWmClass = 67 + AtomWmTransientFor = 68 +) + +// BadAtom is the error number for a BadAtom. +const BadAtom = 5 + +type AtomError ValueError + +// AtomErrorNew constructs a AtomError value that implements xgb.Error from a byte slice. +func AtomErrorNew(buf []byte) xgb.Error { + v := AtomError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Atom" + return v +} + +// SequenceId returns the sequence id attached to the BadAtom error. +// This is mostly used internally. +func (err AtomError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadAtom error. If no bad value exists, 0 is returned. +func (err AtomError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadAtom error. +func (err AtomError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadAtom {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[5] = AtomErrorNew +} + +const ( + AutoRepeatModeOff = 0 + AutoRepeatModeOn = 1 + AutoRepeatModeDefault = 2 +) + +const ( + BackPixmapNone = 0 + BackPixmapParentRelative = 1 +) + +const ( + BackingStoreNotUseful = 0 + BackingStoreWhenMapped = 1 + BackingStoreAlways = 2 +) + +const ( + BlankingNotPreferred = 0 + BlankingPreferred = 1 + BlankingDefault = 2 +) + +type Bool32 uint32 + +type Button byte + +const ( + ButtonIndexAny = 0 + ButtonIndex1 = 1 + ButtonIndex2 = 2 + ButtonIndex3 = 3 + ButtonIndex4 = 4 + ButtonIndex5 = 5 +) + +const ( + ButtonMask1 = 256 + ButtonMask2 = 512 + ButtonMask3 = 1024 + ButtonMask4 = 2048 + ButtonMask5 = 4096 + ButtonMaskAny = 32768 +) + +// ButtonPress is the event number for a ButtonPressEvent. +const ButtonPress = 4 + +type ButtonPressEvent struct { + Sequence uint16 + Detail Button + Time Timestamp + Root Window + Event Window + Child Window + RootX int16 + RootY int16 + EventX int16 + EventY int16 + State uint16 + SameScreen bool + // padding: 1 bytes +} + +// ButtonPressEventNew constructs a ButtonPressEvent value that implements xgb.Event from a byte slice. +func ButtonPressEventNew(buf []byte) xgb.Event { + v := ButtonPressEvent{} + b := 1 // don't read event number + + v.Detail = Button(buf[b]) + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Child = Window(xgb.Get32(buf[b:])) + b += 4 + + v.RootX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RootY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.State = xgb.Get16(buf[b:]) + b += 2 + + if buf[b] == 1 { + v.SameScreen = true + } else { + v.SameScreen = false + } + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a ButtonPressEvent value to a byte slice. +func (v ButtonPressEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 4 + b += 1 + + buf[b] = byte(v.Detail) + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Child)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.RootX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.RootY)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventY)) + b += 2 + + xgb.Put16(buf[b:], v.State) + b += 2 + + if v.SameScreen { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the ButtonPress event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ButtonPressEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ButtonPressEvent. +func (v ButtonPressEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen)) + return "ButtonPress {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[4] = ButtonPressEventNew +} + +// ButtonRelease is the event number for a ButtonReleaseEvent. +const ButtonRelease = 5 + +type ButtonReleaseEvent ButtonPressEvent + +// ButtonReleaseEventNew constructs a ButtonReleaseEvent value that implements xgb.Event from a byte slice. +func ButtonReleaseEventNew(buf []byte) xgb.Event { + return ButtonReleaseEvent(ButtonPressEventNew(buf).(ButtonPressEvent)) +} + +// Bytes writes a ButtonReleaseEvent value to a byte slice. +func (v ButtonReleaseEvent) Bytes() []byte { + buf := ButtonPressEvent(v).Bytes() + buf[0] = 5 + return buf +} + +// SequenceId returns the sequence id attached to the ButtonRelease event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ButtonReleaseEvent) SequenceId() uint16 { + return v.Sequence +} + +func (v ButtonReleaseEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen)) + return "ButtonRelease {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[5] = ButtonReleaseEventNew +} + +const ( + CapStyleNotLast = 0 + CapStyleButt = 1 + CapStyleRound = 2 + CapStyleProjecting = 3 +) + +type Char2b struct { + Byte1 byte + Byte2 byte +} + +// Char2bRead reads a byte slice into a Char2b value. +func Char2bRead(buf []byte, v *Char2b) int { + b := 0 + + v.Byte1 = buf[b] + b += 1 + + v.Byte2 = buf[b] + b += 1 + + return b +} + +// Char2bReadList reads a byte slice into a list of Char2b values. +func Char2bReadList(buf []byte, dest []Char2b) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Char2b{} + b += Char2bRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Char2b value to a byte slice. +func (v Char2b) Bytes() []byte { + buf := make([]byte, 2) + b := 0 + + buf[b] = v.Byte1 + b += 1 + + buf[b] = v.Byte2 + b += 1 + + return buf[:b] +} + +// Char2bListBytes writes a list of Char2b values to a byte slice. +func Char2bListBytes(buf []byte, list []Char2b) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Charinfo struct { + LeftSideBearing int16 + RightSideBearing int16 + CharacterWidth int16 + Ascent int16 + Descent int16 + Attributes uint16 +} + +// CharinfoRead reads a byte slice into a Charinfo value. +func CharinfoRead(buf []byte, v *Charinfo) int { + b := 0 + + v.LeftSideBearing = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RightSideBearing = int16(xgb.Get16(buf[b:])) + b += 2 + + v.CharacterWidth = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Ascent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Descent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Attributes = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// CharinfoReadList reads a byte slice into a list of Charinfo values. +func CharinfoReadList(buf []byte, dest []Charinfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Charinfo{} + b += CharinfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Charinfo value to a byte slice. +func (v Charinfo) Bytes() []byte { + buf := make([]byte, 12) + b := 0 + + xgb.Put16(buf[b:], uint16(v.LeftSideBearing)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.RightSideBearing)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.CharacterWidth)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Ascent)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Descent)) + b += 2 + + xgb.Put16(buf[b:], v.Attributes) + b += 2 + + return buf[:b] +} + +// CharinfoListBytes writes a list of Charinfo values to a byte slice. +func CharinfoListBytes(buf []byte, list []Charinfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + CirculateRaiseLowest = 0 + CirculateLowerHighest = 1 +) + +// CirculateNotify is the event number for a CirculateNotifyEvent. +const CirculateNotify = 26 + +type CirculateNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window + // padding: 4 bytes + Place byte + // padding: 3 bytes +} + +// CirculateNotifyEventNew constructs a CirculateNotifyEvent value that implements xgb.Event from a byte slice. +func CirculateNotifyEventNew(buf []byte) xgb.Event { + v := CirculateNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + b += 4 // padding + + v.Place = buf[b] + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a CirculateNotifyEvent value to a byte slice. +func (v CirculateNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 26 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + b += 4 // padding + + buf[b] = v.Place + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the CirculateNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v CirculateNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of CirculateNotifyEvent. +func (v CirculateNotifyEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Place: %d", v.Place)) + return "CirculateNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[26] = CirculateNotifyEventNew +} + +// CirculateRequest is the event number for a CirculateRequestEvent. +const CirculateRequest = 27 + +type CirculateRequestEvent CirculateNotifyEvent + +// CirculateRequestEventNew constructs a CirculateRequestEvent value that implements xgb.Event from a byte slice. +func CirculateRequestEventNew(buf []byte) xgb.Event { + return CirculateRequestEvent(CirculateNotifyEventNew(buf).(CirculateNotifyEvent)) +} + +// Bytes writes a CirculateRequestEvent value to a byte slice. +func (v CirculateRequestEvent) Bytes() []byte { + buf := CirculateNotifyEvent(v).Bytes() + buf[0] = 27 + return buf +} + +// SequenceId returns the sequence id attached to the CirculateRequest event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v CirculateRequestEvent) SequenceId() uint16 { + return v.Sequence +} + +func (v CirculateRequestEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Place: %d", v.Place)) + return "CirculateRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[27] = CirculateRequestEventNew +} + +// ClientMessage is the event number for a ClientMessageEvent. +const ClientMessage = 33 + +type ClientMessageEvent struct { + Sequence uint16 + Format byte + Window Window + Type Atom + Data ClientMessageDataUnion +} + +// ClientMessageEventNew constructs a ClientMessageEvent value that implements xgb.Event from a byte slice. +func ClientMessageEventNew(buf []byte) xgb.Event { + v := ClientMessageEvent{} + b := 1 // don't read event number + + v.Format = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Type = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Data = ClientMessageDataUnion{} + b += ClientMessageDataUnionRead(buf[b:], &v.Data) + + return v +} + +// Bytes writes a ClientMessageEvent value to a byte slice. +func (v ClientMessageEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 33 + b += 1 + + buf[b] = v.Format + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Type)) + b += 4 + + { + unionBytes := v.Data.Bytes() + copy(buf[b:], unionBytes) + b += len(unionBytes) + } + + return buf +} + +// SequenceId returns the sequence id attached to the ClientMessage event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ClientMessageEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ClientMessageEvent. +func (v ClientMessageEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Format: %d", v.Format)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Type: %d", v.Type)) + return "ClientMessage {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[33] = ClientMessageEventNew +} + +// ClientMessageDataUnion is a represention of the ClientMessageDataUnion union type. +// Note that to *create* a Union, you should *never* create +// this struct directly (unless you know what you're doing). +// Instead use one of the following constructors for 'ClientMessageDataUnion': +// +// ClientMessageDataUnionData8New(Data8 []byte) ClientMessageDataUnion +// ClientMessageDataUnionData16New(Data16 []uint16) ClientMessageDataUnion +// ClientMessageDataUnionData32New(Data32 []uint32) ClientMessageDataUnion +type ClientMessageDataUnion struct { + Data8 []byte // size: 20 + Data16 []uint16 // size: 20 + Data32 []uint32 // size: 20 +} + +// ClientMessageDataUnionData8New constructs a new ClientMessageDataUnion union type with the Data8 field. +func ClientMessageDataUnionData8New(Data8 []byte) ClientMessageDataUnion { + var b int + buf := make([]byte, 20) + + copy(buf[b:], Data8[:20]) + b += int(20) + + // Create the Union type + v := ClientMessageDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Data8 = make([]byte, 20) + copy(v.Data8[:20], buf[b:]) + b += int(20) + + b = 0 // always read the same bytes + v.Data16 = make([]uint16, 10) + for i := 0; i < int(10); i++ { + v.Data16[i] = xgb.Get16(buf[b:]) + b += 2 + } + + b = 0 // always read the same bytes + v.Data32 = make([]uint32, 5) + for i := 0; i < int(5); i++ { + v.Data32[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// ClientMessageDataUnionData16New constructs a new ClientMessageDataUnion union type with the Data16 field. +func ClientMessageDataUnionData16New(Data16 []uint16) ClientMessageDataUnion { + var b int + buf := make([]byte, 20) + + for i := 0; i < int(10); i++ { + xgb.Put16(buf[b:], Data16[i]) + b += 2 + } + + // Create the Union type + v := ClientMessageDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Data8 = make([]byte, 20) + copy(v.Data8[:20], buf[b:]) + b += int(20) + + b = 0 // always read the same bytes + v.Data16 = make([]uint16, 10) + for i := 0; i < int(10); i++ { + v.Data16[i] = xgb.Get16(buf[b:]) + b += 2 + } + + b = 0 // always read the same bytes + v.Data32 = make([]uint32, 5) + for i := 0; i < int(5); i++ { + v.Data32[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// ClientMessageDataUnionData32New constructs a new ClientMessageDataUnion union type with the Data32 field. +func ClientMessageDataUnionData32New(Data32 []uint32) ClientMessageDataUnion { + var b int + buf := make([]byte, 20) + + for i := 0; i < int(5); i++ { + xgb.Put32(buf[b:], Data32[i]) + b += 4 + } + + // Create the Union type + v := ClientMessageDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Data8 = make([]byte, 20) + copy(v.Data8[:20], buf[b:]) + b += int(20) + + b = 0 // always read the same bytes + v.Data16 = make([]uint16, 10) + for i := 0; i < int(10); i++ { + v.Data16[i] = xgb.Get16(buf[b:]) + b += 2 + } + + b = 0 // always read the same bytes + v.Data32 = make([]uint32, 5) + for i := 0; i < int(5); i++ { + v.Data32[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// ClientMessageDataUnionRead reads a byte slice into a ClientMessageDataUnion value. +func ClientMessageDataUnionRead(buf []byte, v *ClientMessageDataUnion) int { + var b int + + b = 0 // re-read the same bytes + v.Data8 = make([]byte, 20) + copy(v.Data8[:20], buf[b:]) + b += int(20) + + b = 0 // re-read the same bytes + v.Data16 = make([]uint16, 10) + for i := 0; i < int(10); i++ { + v.Data16[i] = xgb.Get16(buf[b:]) + b += 2 + } + + b = 0 // re-read the same bytes + v.Data32 = make([]uint32, 5) + for i := 0; i < int(5); i++ { + v.Data32[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return 20 +} + +// ClientMessageDataUnionReadList reads a byte slice into a list of ClientMessageDataUnion values. +func ClientMessageDataUnionReadList(buf []byte, dest []ClientMessageDataUnion) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ClientMessageDataUnion{} + b += ClientMessageDataUnionRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ClientMessageDataUnion value to a byte slice. +// Each field in a union must contain the same data. +// So simply pick the first field and write that to the wire. +func (v ClientMessageDataUnion) Bytes() []byte { + buf := make([]byte, 20) + b := 0 + + copy(buf[b:], v.Data8[:20]) + b += int(20) + return buf +} + +// ClientMessageDataUnionListBytes writes a list of ClientMessageDataUnion values to a byte slice. +func ClientMessageDataUnionListBytes(buf []byte, list []ClientMessageDataUnion) int { + b := 0 + var unionBytes []byte + for _, item := range list { + unionBytes = item.Bytes() + copy(buf[b:], unionBytes) + b += xgb.Pad(len(unionBytes)) + } + return b +} + +const ( + ClipOrderingUnsorted = 0 + ClipOrderingYSorted = 1 + ClipOrderingYXSorted = 2 + ClipOrderingYXBanded = 3 +) + +const ( + CloseDownDestroyAll = 0 + CloseDownRetainPermanent = 1 + CloseDownRetainTemporary = 2 +) + +const ( + ColorFlagRed = 1 + ColorFlagGreen = 2 + ColorFlagBlue = 4 +) + +type Coloritem struct { + Pixel uint32 + Red uint16 + Green uint16 + Blue uint16 + Flags byte + // padding: 1 bytes +} + +// ColoritemRead reads a byte slice into a Coloritem value. +func ColoritemRead(buf []byte, v *Coloritem) int { + b := 0 + + v.Pixel = xgb.Get32(buf[b:]) + b += 4 + + v.Red = xgb.Get16(buf[b:]) + b += 2 + + v.Green = xgb.Get16(buf[b:]) + b += 2 + + v.Blue = xgb.Get16(buf[b:]) + b += 2 + + v.Flags = buf[b] + b += 1 + + b += 1 // padding + + return b +} + +// ColoritemReadList reads a byte slice into a list of Coloritem values. +func ColoritemReadList(buf []byte, dest []Coloritem) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Coloritem{} + b += ColoritemRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Coloritem value to a byte slice. +func (v Coloritem) Bytes() []byte { + buf := make([]byte, 12) + b := 0 + + xgb.Put32(buf[b:], v.Pixel) + b += 4 + + xgb.Put16(buf[b:], v.Red) + b += 2 + + xgb.Put16(buf[b:], v.Green) + b += 2 + + xgb.Put16(buf[b:], v.Blue) + b += 2 + + buf[b] = v.Flags + b += 1 + + b += 1 // padding + + return buf[:b] +} + +// ColoritemListBytes writes a list of Coloritem values to a byte slice. +func ColoritemListBytes(buf []byte, list []Coloritem) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Colormap uint32 + +func NewColormapId(c *xgb.Conn) (Colormap, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Colormap(id), nil +} + +const ( + ColormapNone = 0 +) + +// BadColormap is the error number for a BadColormap. +const BadColormap = 12 + +type ColormapError ValueError + +// ColormapErrorNew constructs a ColormapError value that implements xgb.Error from a byte slice. +func ColormapErrorNew(buf []byte) xgb.Error { + v := ColormapError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Colormap" + return v +} + +// SequenceId returns the sequence id attached to the BadColormap error. +// This is mostly used internally. +func (err ColormapError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadColormap error. If no bad value exists, 0 is returned. +func (err ColormapError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadColormap error. +func (err ColormapError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadColormap {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[12] = ColormapErrorNew +} + +const ( + ColormapAllocNone = 0 + ColormapAllocAll = 1 +) + +// ColormapNotify is the event number for a ColormapNotifyEvent. +const ColormapNotify = 32 + +type ColormapNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Window Window + Colormap Colormap + New bool + State byte + // padding: 2 bytes +} + +// ColormapNotifyEventNew constructs a ColormapNotifyEvent value that implements xgb.Event from a byte slice. +func ColormapNotifyEventNew(buf []byte) xgb.Event { + v := ColormapNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Colormap = Colormap(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.New = true + } else { + v.New = false + } + b += 1 + + v.State = buf[b] + b += 1 + + b += 2 // padding + + return v +} + +// Bytes writes a ColormapNotifyEvent value to a byte slice. +func (v ColormapNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 32 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Colormap)) + b += 4 + + if v.New { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + buf[b] = v.State + b += 1 + + b += 2 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the ColormapNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ColormapNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ColormapNotifyEvent. +func (v ColormapNotifyEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Colormap: %d", v.Colormap)) + fieldVals = append(fieldVals, xgb.Sprintf("New: %t", v.New)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + return "ColormapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[32] = ColormapNotifyEventNew +} + +const ( + ColormapStateUninstalled = 0 + ColormapStateInstalled = 1 +) + +const ( + ConfigWindowX = 1 + ConfigWindowY = 2 + ConfigWindowWidth = 4 + ConfigWindowHeight = 8 + ConfigWindowBorderWidth = 16 + ConfigWindowSibling = 32 + ConfigWindowStackMode = 64 +) + +// ConfigureNotify is the event number for a ConfigureNotifyEvent. +const ConfigureNotify = 22 + +type ConfigureNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window + AboveSibling Window + X int16 + Y int16 + Width uint16 + Height uint16 + BorderWidth uint16 + OverrideRedirect bool + // padding: 1 bytes +} + +// ConfigureNotifyEventNew constructs a ConfigureNotifyEvent value that implements xgb.Event from a byte slice. +func ConfigureNotifyEventNew(buf []byte) xgb.Event { + v := ConfigureNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.AboveSibling = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.BorderWidth = xgb.Get16(buf[b:]) + b += 2 + + if buf[b] == 1 { + v.OverrideRedirect = true + } else { + v.OverrideRedirect = false + } + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a ConfigureNotifyEvent value to a byte slice. +func (v ConfigureNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 22 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.AboveSibling)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.BorderWidth) + b += 2 + + if v.OverrideRedirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the ConfigureNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ConfigureNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ConfigureNotifyEvent. +func (v ConfigureNotifyEvent) String() string { + fieldVals := make([]string, 0, 11) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("AboveSibling: %d", v.AboveSibling)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("BorderWidth: %d", v.BorderWidth)) + fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect)) + return "ConfigureNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[22] = ConfigureNotifyEventNew +} + +// ConfigureRequest is the event number for a ConfigureRequestEvent. +const ConfigureRequest = 23 + +type ConfigureRequestEvent struct { + Sequence uint16 + StackMode byte + Parent Window + Window Window + Sibling Window + X int16 + Y int16 + Width uint16 + Height uint16 + BorderWidth uint16 + ValueMask uint16 +} + +// ConfigureRequestEventNew constructs a ConfigureRequestEvent value that implements xgb.Event from a byte slice. +func ConfigureRequestEventNew(buf []byte) xgb.Event { + v := ConfigureRequestEvent{} + b := 1 // don't read event number + + v.StackMode = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Parent = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Sibling = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.BorderWidth = xgb.Get16(buf[b:]) + b += 2 + + v.ValueMask = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Bytes writes a ConfigureRequestEvent value to a byte slice. +func (v ConfigureRequestEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 23 + b += 1 + + buf[b] = v.StackMode + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Parent)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Sibling)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.BorderWidth) + b += 2 + + xgb.Put16(buf[b:], v.ValueMask) + b += 2 + + return buf +} + +// SequenceId returns the sequence id attached to the ConfigureRequest event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ConfigureRequestEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ConfigureRequestEvent. +func (v ConfigureRequestEvent) String() string { + fieldVals := make([]string, 0, 10) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("StackMode: %d", v.StackMode)) + fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Sibling: %d", v.Sibling)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("BorderWidth: %d", v.BorderWidth)) + fieldVals = append(fieldVals, xgb.Sprintf("ValueMask: %d", v.ValueMask)) + return "ConfigureRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[23] = ConfigureRequestEventNew +} + +const ( + CoordModeOrigin = 0 + CoordModePrevious = 1 +) + +// CreateNotify is the event number for a CreateNotifyEvent. +const CreateNotify = 16 + +type CreateNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Parent Window + Window Window + X int16 + Y int16 + Width uint16 + Height uint16 + BorderWidth uint16 + OverrideRedirect bool + // padding: 1 bytes +} + +// CreateNotifyEventNew constructs a CreateNotifyEvent value that implements xgb.Event from a byte slice. +func CreateNotifyEventNew(buf []byte) xgb.Event { + v := CreateNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Parent = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.BorderWidth = xgb.Get16(buf[b:]) + b += 2 + + if buf[b] == 1 { + v.OverrideRedirect = true + } else { + v.OverrideRedirect = false + } + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a CreateNotifyEvent value to a byte slice. +func (v CreateNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 16 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Parent)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.BorderWidth) + b += 2 + + if v.OverrideRedirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the CreateNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v CreateNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of CreateNotifyEvent. +func (v CreateNotifyEvent) String() string { + fieldVals := make([]string, 0, 10) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("BorderWidth: %d", v.BorderWidth)) + fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect)) + return "CreateNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[16] = CreateNotifyEventNew +} + +type Cursor uint32 + +func NewCursorId(c *xgb.Conn) (Cursor, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Cursor(id), nil +} + +const ( + CursorNone = 0 +) + +// BadCursor is the error number for a BadCursor. +const BadCursor = 6 + +type CursorError ValueError + +// CursorErrorNew constructs a CursorError value that implements xgb.Error from a byte slice. +func CursorErrorNew(buf []byte) xgb.Error { + v := CursorError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Cursor" + return v +} + +// SequenceId returns the sequence id attached to the BadCursor error. +// This is mostly used internally. +func (err CursorError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadCursor error. If no bad value exists, 0 is returned. +func (err CursorError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadCursor error. +func (err CursorError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadCursor {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[6] = CursorErrorNew +} + +const ( + CwBackPixmap = 1 + CwBackPixel = 2 + CwBorderPixmap = 4 + CwBorderPixel = 8 + CwBitGravity = 16 + CwWinGravity = 32 + CwBackingStore = 64 + CwBackingPlanes = 128 + CwBackingPixel = 256 + CwOverrideRedirect = 512 + CwSaveUnder = 1024 + CwEventMask = 2048 + CwDontPropagate = 4096 + CwColormap = 8192 + CwCursor = 16384 +) + +type DepthInfo struct { + Depth byte + // padding: 1 bytes + VisualsLen uint16 + // padding: 4 bytes + Visuals []VisualInfo // size: xgb.Pad((int(VisualsLen) * 24)) +} + +// DepthInfoRead reads a byte slice into a DepthInfo value. +func DepthInfoRead(buf []byte, v *DepthInfo) int { + b := 0 + + v.Depth = buf[b] + b += 1 + + b += 1 // padding + + v.VisualsLen = xgb.Get16(buf[b:]) + b += 2 + + b += 4 // padding + + v.Visuals = make([]VisualInfo, v.VisualsLen) + b += VisualInfoReadList(buf[b:], v.Visuals) + + return b +} + +// DepthInfoReadList reads a byte slice into a list of DepthInfo values. +func DepthInfoReadList(buf []byte, dest []DepthInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = DepthInfo{} + b += DepthInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a DepthInfo value to a byte slice. +func (v DepthInfo) Bytes() []byte { + buf := make([]byte, (8 + xgb.Pad((int(v.VisualsLen) * 24)))) + b := 0 + + buf[b] = v.Depth + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], v.VisualsLen) + b += 2 + + b += 4 // padding + + b += VisualInfoListBytes(buf[b:], v.Visuals) + + return buf[:b] +} + +// DepthInfoListBytes writes a list of DepthInfo values to a byte slice. +func DepthInfoListBytes(buf []byte, list []DepthInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// DepthInfoListSize computes the size (bytes) of a list of DepthInfo values. +func DepthInfoListSize(list []DepthInfo) int { + size := 0 + for _, item := range list { + size += (8 + xgb.Pad((int(item.VisualsLen) * 24))) + } + return size +} + +// DestroyNotify is the event number for a DestroyNotifyEvent. +const DestroyNotify = 17 + +type DestroyNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window +} + +// DestroyNotifyEventNew constructs a DestroyNotifyEvent value that implements xgb.Event from a byte slice. +func DestroyNotifyEventNew(buf []byte) xgb.Event { + v := DestroyNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a DestroyNotifyEvent value to a byte slice. +func (v DestroyNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 17 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the DestroyNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v DestroyNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of DestroyNotifyEvent. +func (v DestroyNotifyEvent) String() string { + fieldVals := make([]string, 0, 3) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + return "DestroyNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[17] = DestroyNotifyEventNew +} + +type Drawable uint32 + +func NewDrawableId(c *xgb.Conn) (Drawable, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Drawable(id), nil +} + +// BadDrawable is the error number for a BadDrawable. +const BadDrawable = 9 + +type DrawableError ValueError + +// DrawableErrorNew constructs a DrawableError value that implements xgb.Error from a byte slice. +func DrawableErrorNew(buf []byte) xgb.Error { + v := DrawableError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Drawable" + return v +} + +// SequenceId returns the sequence id attached to the BadDrawable error. +// This is mostly used internally. +func (err DrawableError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadDrawable error. If no bad value exists, 0 is returned. +func (err DrawableError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadDrawable error. +func (err DrawableError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadDrawable {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[9] = DrawableErrorNew +} + +// EnterNotify is the event number for a EnterNotifyEvent. +const EnterNotify = 7 + +type EnterNotifyEvent struct { + Sequence uint16 + Detail byte + Time Timestamp + Root Window + Event Window + Child Window + RootX int16 + RootY int16 + EventX int16 + EventY int16 + State uint16 + Mode byte + SameScreenFocus byte +} + +// EnterNotifyEventNew constructs a EnterNotifyEvent value that implements xgb.Event from a byte slice. +func EnterNotifyEventNew(buf []byte) xgb.Event { + v := EnterNotifyEvent{} + b := 1 // don't read event number + + v.Detail = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Child = Window(xgb.Get32(buf[b:])) + b += 4 + + v.RootX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RootY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.State = xgb.Get16(buf[b:]) + b += 2 + + v.Mode = buf[b] + b += 1 + + v.SameScreenFocus = buf[b] + b += 1 + + return v +} + +// Bytes writes a EnterNotifyEvent value to a byte slice. +func (v EnterNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 7 + b += 1 + + buf[b] = v.Detail + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Child)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.RootX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.RootY)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventY)) + b += 2 + + xgb.Put16(buf[b:], v.State) + b += 2 + + buf[b] = v.Mode + b += 1 + + buf[b] = v.SameScreenFocus + b += 1 + + return buf +} + +// SequenceId returns the sequence id attached to the EnterNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v EnterNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of EnterNotifyEvent. +func (v EnterNotifyEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreenFocus: %d", v.SameScreenFocus)) + return "EnterNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[7] = EnterNotifyEventNew +} + +const ( + EventMaskNoEvent = 0 + EventMaskKeyPress = 1 + EventMaskKeyRelease = 2 + EventMaskButtonPress = 4 + EventMaskButtonRelease = 8 + EventMaskEnterWindow = 16 + EventMaskLeaveWindow = 32 + EventMaskPointerMotion = 64 + EventMaskPointerMotionHint = 128 + EventMaskButton1Motion = 256 + EventMaskButton2Motion = 512 + EventMaskButton3Motion = 1024 + EventMaskButton4Motion = 2048 + EventMaskButton5Motion = 4096 + EventMaskButtonMotion = 8192 + EventMaskKeymapState = 16384 + EventMaskExposure = 32768 + EventMaskVisibilityChange = 65536 + EventMaskStructureNotify = 131072 + EventMaskResizeRedirect = 262144 + EventMaskSubstructureNotify = 524288 + EventMaskSubstructureRedirect = 1048576 + EventMaskFocusChange = 2097152 + EventMaskPropertyChange = 4194304 + EventMaskColorMapChange = 8388608 + EventMaskOwnerGrabButton = 16777216 +) + +// Expose is the event number for a ExposeEvent. +const Expose = 12 + +type ExposeEvent struct { + Sequence uint16 + // padding: 1 bytes + Window Window + X uint16 + Y uint16 + Width uint16 + Height uint16 + Count uint16 + // padding: 2 bytes +} + +// ExposeEventNew constructs a ExposeEvent value that implements xgb.Event from a byte slice. +func ExposeEventNew(buf []byte) xgb.Event { + v := ExposeEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = xgb.Get16(buf[b:]) + b += 2 + + v.Y = xgb.Get16(buf[b:]) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.Count = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + return v +} + +// Bytes writes a ExposeEvent value to a byte slice. +func (v ExposeEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 12 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put16(buf[b:], v.X) + b += 2 + + xgb.Put16(buf[b:], v.Y) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.Count) + b += 2 + + b += 2 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the Expose event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ExposeEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ExposeEvent. +func (v ExposeEvent) String() string { + fieldVals := make([]string, 0, 8) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count)) + return "Expose {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[12] = ExposeEventNew +} + +const ( + ExposuresNotAllowed = 0 + ExposuresAllowed = 1 + ExposuresDefault = 2 +) + +const ( + FamilyInternet = 0 + FamilyDECnet = 1 + FamilyChaos = 2 + FamilyServerInterpreted = 5 + FamilyInternet6 = 6 +) + +const ( + FillRuleEvenOdd = 0 + FillRuleWinding = 1 +) + +const ( + FillStyleSolid = 0 + FillStyleTiled = 1 + FillStyleStippled = 2 + FillStyleOpaqueStippled = 3 +) + +// FocusIn is the event number for a FocusInEvent. +const FocusIn = 9 + +type FocusInEvent struct { + Sequence uint16 + Detail byte + Event Window + Mode byte + // padding: 3 bytes +} + +// FocusInEventNew constructs a FocusInEvent value that implements xgb.Event from a byte slice. +func FocusInEventNew(buf []byte) xgb.Event { + v := FocusInEvent{} + b := 1 // don't read event number + + v.Detail = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Mode = buf[b] + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a FocusInEvent value to a byte slice. +func (v FocusInEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 9 + b += 1 + + buf[b] = v.Detail + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + buf[b] = v.Mode + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the FocusIn event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v FocusInEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of FocusInEvent. +func (v FocusInEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode)) + return "FocusIn {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[9] = FocusInEventNew +} + +// FocusOut is the event number for a FocusOutEvent. +const FocusOut = 10 + +type FocusOutEvent FocusInEvent + +// FocusOutEventNew constructs a FocusOutEvent value that implements xgb.Event from a byte slice. +func FocusOutEventNew(buf []byte) xgb.Event { + return FocusOutEvent(FocusInEventNew(buf).(FocusInEvent)) +} + +// Bytes writes a FocusOutEvent value to a byte slice. +func (v FocusOutEvent) Bytes() []byte { + buf := FocusInEvent(v).Bytes() + buf[0] = 10 + return buf +} + +// SequenceId returns the sequence id attached to the FocusOut event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v FocusOutEvent) SequenceId() uint16 { + return v.Sequence +} + +func (v FocusOutEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode)) + return "FocusOut {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[10] = FocusOutEventNew +} + +type Font uint32 + +func NewFontId(c *xgb.Conn) (Font, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Font(id), nil +} + +// BadFont is the error number for a BadFont. +const BadFont = 7 + +type FontError ValueError + +// FontErrorNew constructs a FontError value that implements xgb.Error from a byte slice. +func FontErrorNew(buf []byte) xgb.Error { + v := FontError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Font" + return v +} + +// SequenceId returns the sequence id attached to the BadFont error. +// This is mostly used internally. +func (err FontError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadFont error. If no bad value exists, 0 is returned. +func (err FontError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadFont error. +func (err FontError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadFont {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[7] = FontErrorNew +} + +const ( + FontNone = 0 +) + +const ( + FontDrawLeftToRight = 0 + FontDrawRightToLeft = 1 +) + +type Fontable uint32 + +func NewFontableId(c *xgb.Conn) (Fontable, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Fontable(id), nil +} + +type Fontprop struct { + Name Atom + Value uint32 +} + +// FontpropRead reads a byte slice into a Fontprop value. +func FontpropRead(buf []byte, v *Fontprop) int { + b := 0 + + v.Name = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Value = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// FontpropReadList reads a byte slice into a list of Fontprop values. +func FontpropReadList(buf []byte, dest []Fontprop) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Fontprop{} + b += FontpropRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Fontprop value to a byte slice. +func (v Fontprop) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Name)) + b += 4 + + xgb.Put32(buf[b:], v.Value) + b += 4 + + return buf[:b] +} + +// FontpropListBytes writes a list of Fontprop values to a byte slice. +func FontpropListBytes(buf []byte, list []Fontprop) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Format struct { + Depth byte + BitsPerPixel byte + ScanlinePad byte + // padding: 5 bytes +} + +// FormatRead reads a byte slice into a Format value. +func FormatRead(buf []byte, v *Format) int { + b := 0 + + v.Depth = buf[b] + b += 1 + + v.BitsPerPixel = buf[b] + b += 1 + + v.ScanlinePad = buf[b] + b += 1 + + b += 5 // padding + + return b +} + +// FormatReadList reads a byte slice into a list of Format values. +func FormatReadList(buf []byte, dest []Format) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Format{} + b += FormatRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Format value to a byte slice. +func (v Format) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + buf[b] = v.Depth + b += 1 + + buf[b] = v.BitsPerPixel + b += 1 + + buf[b] = v.ScanlinePad + b += 1 + + b += 5 // padding + + return buf[:b] +} + +// FormatListBytes writes a list of Format values to a byte slice. +func FormatListBytes(buf []byte, list []Format) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// BadGContext is the error number for a BadGContext. +const BadGContext = 13 + +type GContextError ValueError + +// GContextErrorNew constructs a GContextError value that implements xgb.Error from a byte slice. +func GContextErrorNew(buf []byte) xgb.Error { + v := GContextError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "GContext" + return v +} + +// SequenceId returns the sequence id attached to the BadGContext error. +// This is mostly used internally. +func (err GContextError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadGContext error. If no bad value exists, 0 is returned. +func (err GContextError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadGContext error. +func (err GContextError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadGContext {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[13] = GContextErrorNew +} + +const ( + GcFunction = 1 + GcPlaneMask = 2 + GcForeground = 4 + GcBackground = 8 + GcLineWidth = 16 + GcLineStyle = 32 + GcCapStyle = 64 + GcJoinStyle = 128 + GcFillStyle = 256 + GcFillRule = 512 + GcTile = 1024 + GcStipple = 2048 + GcTileStippleOriginX = 4096 + GcTileStippleOriginY = 8192 + GcFont = 16384 + GcSubwindowMode = 32768 + GcGraphicsExposures = 65536 + GcClipOriginX = 131072 + GcClipOriginY = 262144 + GcClipMask = 524288 + GcDashOffset = 1048576 + GcDashList = 2097152 + GcArcMode = 4194304 +) + +type Gcontext uint32 + +func NewGcontextId(c *xgb.Conn) (Gcontext, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Gcontext(id), nil +} + +// GeGeneric is the event number for a GeGenericEvent. +const GeGeneric = 35 + +type GeGenericEvent struct { + Sequence uint16 + // padding: 22 bytes +} + +// GeGenericEventNew constructs a GeGenericEvent value that implements xgb.Event from a byte slice. +func GeGenericEventNew(buf []byte) xgb.Event { + v := GeGenericEvent{} + b := 1 // don't read event number + + b += 22 // padding + + return v +} + +// Bytes writes a GeGenericEvent value to a byte slice. +func (v GeGenericEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 35 + b += 1 + + b += 22 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the GeGeneric event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v GeGenericEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of GeGenericEvent. +func (v GeGenericEvent) String() string { + fieldVals := make([]string, 0, 1) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + return "GeGeneric {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[35] = GeGenericEventNew +} + +const ( + GetPropertyTypeAny = 0 +) + +const ( + GrabAny = 0 +) + +const ( + GrabModeSync = 0 + GrabModeAsync = 1 +) + +const ( + GrabStatusSuccess = 0 + GrabStatusAlreadyGrabbed = 1 + GrabStatusInvalidTime = 2 + GrabStatusNotViewable = 3 + GrabStatusFrozen = 4 +) + +// GraphicsExposure is the event number for a GraphicsExposureEvent. +const GraphicsExposure = 13 + +type GraphicsExposureEvent struct { + Sequence uint16 + // padding: 1 bytes + Drawable Drawable + X uint16 + Y uint16 + Width uint16 + Height uint16 + MinorOpcode uint16 + Count uint16 + MajorOpcode byte + // padding: 3 bytes +} + +// GraphicsExposureEventNew constructs a GraphicsExposureEvent value that implements xgb.Event from a byte slice. +func GraphicsExposureEventNew(buf []byte) xgb.Event { + v := GraphicsExposureEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Drawable = Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.X = xgb.Get16(buf[b:]) + b += 2 + + v.Y = xgb.Get16(buf[b:]) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.MinorOpcode = xgb.Get16(buf[b:]) + b += 2 + + v.Count = xgb.Get16(buf[b:]) + b += 2 + + v.MajorOpcode = buf[b] + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a GraphicsExposureEvent value to a byte slice. +func (v GraphicsExposureEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 13 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put16(buf[b:], v.X) + b += 2 + + xgb.Put16(buf[b:], v.Y) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put16(buf[b:], v.MinorOpcode) + b += 2 + + xgb.Put16(buf[b:], v.Count) + b += 2 + + buf[b] = v.MajorOpcode + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the GraphicsExposure event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v GraphicsExposureEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of GraphicsExposureEvent. +func (v GraphicsExposureEvent) String() string { + fieldVals := make([]string, 0, 10) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", v.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", v.MajorOpcode)) + return "GraphicsExposure {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[13] = GraphicsExposureEventNew +} + +const ( + GravityBitForget = 0 + GravityWinUnmap = 0 + GravityNorthWest = 1 + GravityNorth = 2 + GravityNorthEast = 3 + GravityWest = 4 + GravityCenter = 5 + GravityEast = 6 + GravitySouthWest = 7 + GravitySouth = 8 + GravitySouthEast = 9 + GravityStatic = 10 +) + +// GravityNotify is the event number for a GravityNotifyEvent. +const GravityNotify = 24 + +type GravityNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window + X int16 + Y int16 +} + +// GravityNotifyEventNew constructs a GravityNotifyEvent value that implements xgb.Event from a byte slice. +func GravityNotifyEventNew(buf []byte) xgb.Event { + v := GravityNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + return v +} + +// Bytes writes a GravityNotifyEvent value to a byte slice. +func (v GravityNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 24 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + return buf +} + +// SequenceId returns the sequence id attached to the GravityNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v GravityNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of GravityNotifyEvent. +func (v GravityNotifyEvent) String() string { + fieldVals := make([]string, 0, 5) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + return "GravityNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[24] = GravityNotifyEventNew +} + +const ( + GxClear = 0 + GxAnd = 1 + GxAndReverse = 2 + GxCopy = 3 + GxAndInverted = 4 + GxNoop = 5 + GxXor = 6 + GxOr = 7 + GxNor = 8 + GxEquiv = 9 + GxInvert = 10 + GxOrReverse = 11 + GxCopyInverted = 12 + GxOrInverted = 13 + GxNand = 14 + GxSet = 15 +) + +type Host struct { + Family byte + // padding: 1 bytes + AddressLen uint16 + Address []byte // size: xgb.Pad((int(AddressLen) * 1)) + // alignment gap to multiple of 4 +} + +// HostRead reads a byte slice into a Host value. +func HostRead(buf []byte, v *Host) int { + b := 0 + + v.Family = buf[b] + b += 1 + + b += 1 // padding + + v.AddressLen = xgb.Get16(buf[b:]) + b += 2 + + v.Address = make([]byte, v.AddressLen) + copy(v.Address[:v.AddressLen], buf[b:]) + b += int(v.AddressLen) + + b = (b + 3) & ^3 // alignment gap + + return b +} + +// HostReadList reads a byte slice into a list of Host values. +func HostReadList(buf []byte, dest []Host) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Host{} + b += HostRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Host value to a byte slice. +func (v Host) Bytes() []byte { + buf := make([]byte, ((4 + xgb.Pad((int(v.AddressLen) * 1))) + 4)) + b := 0 + + buf[b] = v.Family + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], v.AddressLen) + b += 2 + + copy(buf[b:], v.Address[:v.AddressLen]) + b += int(v.AddressLen) + + b = (b + 3) & ^3 // alignment gap + + return buf[:b] +} + +// HostListBytes writes a list of Host values to a byte slice. +func HostListBytes(buf []byte, list []Host) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// HostListSize computes the size (bytes) of a list of Host values. +func HostListSize(list []Host) int { + size := 0 + for _, item := range list { + size += ((4 + xgb.Pad((int(item.AddressLen) * 1))) + 4) + } + return size +} + +const ( + HostModeInsert = 0 + HostModeDelete = 1 +) + +// BadIDChoice is the error number for a BadIDChoice. +const BadIDChoice = 14 + +type IDChoiceError ValueError + +// IDChoiceErrorNew constructs a IDChoiceError value that implements xgb.Error from a byte slice. +func IDChoiceErrorNew(buf []byte) xgb.Error { + v := IDChoiceError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "IDChoice" + return v +} + +// SequenceId returns the sequence id attached to the BadIDChoice error. +// This is mostly used internally. +func (err IDChoiceError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadIDChoice error. If no bad value exists, 0 is returned. +func (err IDChoiceError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadIDChoice error. +func (err IDChoiceError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadIDChoice {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[14] = IDChoiceErrorNew +} + +const ( + ImageFormatXYBitmap = 0 + ImageFormatXYPixmap = 1 + ImageFormatZPixmap = 2 +) + +const ( + ImageOrderLSBFirst = 0 + ImageOrderMSBFirst = 1 +) + +// BadImplementation is the error number for a BadImplementation. +const BadImplementation = 17 + +type ImplementationError RequestError + +// ImplementationErrorNew constructs a ImplementationError value that implements xgb.Error from a byte slice. +func ImplementationErrorNew(buf []byte) xgb.Error { + v := ImplementationError(RequestErrorNew(buf).(RequestError)) + v.NiceName = "Implementation" + return v +} + +// SequenceId returns the sequence id attached to the BadImplementation error. +// This is mostly used internally. +func (err ImplementationError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadImplementation error. If no bad value exists, 0 is returned. +func (err ImplementationError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadImplementation error. +func (err ImplementationError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadImplementation {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[17] = ImplementationErrorNew +} + +const ( + InputFocusNone = 0 + InputFocusPointerRoot = 1 + InputFocusParent = 2 + InputFocusFollowKeyboard = 3 +) + +const ( + JoinStyleMiter = 0 + JoinStyleRound = 1 + JoinStyleBevel = 2 +) + +const ( + KbKeyClickPercent = 1 + KbBellPercent = 2 + KbBellPitch = 4 + KbBellDuration = 8 + KbLed = 16 + KbLedMode = 32 + KbKey = 64 + KbAutoRepeatMode = 128 +) + +const ( + KeyButMaskShift = 1 + KeyButMaskLock = 2 + KeyButMaskControl = 4 + KeyButMaskMod1 = 8 + KeyButMaskMod2 = 16 + KeyButMaskMod3 = 32 + KeyButMaskMod4 = 64 + KeyButMaskMod5 = 128 + KeyButMaskButton1 = 256 + KeyButMaskButton2 = 512 + KeyButMaskButton3 = 1024 + KeyButMaskButton4 = 2048 + KeyButMaskButton5 = 4096 +) + +// KeyPress is the event number for a KeyPressEvent. +const KeyPress = 2 + +type KeyPressEvent struct { + Sequence uint16 + Detail Keycode + Time Timestamp + Root Window + Event Window + Child Window + RootX int16 + RootY int16 + EventX int16 + EventY int16 + State uint16 + SameScreen bool + // padding: 1 bytes +} + +// KeyPressEventNew constructs a KeyPressEvent value that implements xgb.Event from a byte slice. +func KeyPressEventNew(buf []byte) xgb.Event { + v := KeyPressEvent{} + b := 1 // don't read event number + + v.Detail = Keycode(buf[b]) + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Child = Window(xgb.Get32(buf[b:])) + b += 4 + + v.RootX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RootY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.State = xgb.Get16(buf[b:]) + b += 2 + + if buf[b] == 1 { + v.SameScreen = true + } else { + v.SameScreen = false + } + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a KeyPressEvent value to a byte slice. +func (v KeyPressEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 2 + b += 1 + + buf[b] = byte(v.Detail) + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Child)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.RootX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.RootY)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventY)) + b += 2 + + xgb.Put16(buf[b:], v.State) + b += 2 + + if v.SameScreen { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the KeyPress event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v KeyPressEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of KeyPressEvent. +func (v KeyPressEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen)) + return "KeyPress {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[2] = KeyPressEventNew +} + +// KeyRelease is the event number for a KeyReleaseEvent. +const KeyRelease = 3 + +type KeyReleaseEvent KeyPressEvent + +// KeyReleaseEventNew constructs a KeyReleaseEvent value that implements xgb.Event from a byte slice. +func KeyReleaseEventNew(buf []byte) xgb.Event { + return KeyReleaseEvent(KeyPressEventNew(buf).(KeyPressEvent)) +} + +// Bytes writes a KeyReleaseEvent value to a byte slice. +func (v KeyReleaseEvent) Bytes() []byte { + buf := KeyPressEvent(v).Bytes() + buf[0] = 3 + return buf +} + +// SequenceId returns the sequence id attached to the KeyRelease event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v KeyReleaseEvent) SequenceId() uint16 { + return v.Sequence +} + +func (v KeyReleaseEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen)) + return "KeyRelease {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[3] = KeyReleaseEventNew +} + +type Keycode byte + +type Keycode32 uint32 + +// KeymapNotify is the event number for a KeymapNotifyEvent. +const KeymapNotify = 11 + +type KeymapNotifyEvent struct { + Keys []byte // size: 32 +} + +// KeymapNotifyEventNew constructs a KeymapNotifyEvent value that implements xgb.Event from a byte slice. +func KeymapNotifyEventNew(buf []byte) xgb.Event { + v := KeymapNotifyEvent{} + b := 1 // don't read event number + + v.Keys = make([]byte, 31) + copy(v.Keys[:31], buf[b:]) + b += int(31) + + return v +} + +// Bytes writes a KeymapNotifyEvent value to a byte slice. +func (v KeymapNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 11 + b += 1 + + copy(buf[b:], v.Keys[:31]) + b += int(31) + + return buf +} + +// SequenceId returns the sequence id attached to the KeymapNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v KeymapNotifyEvent) SequenceId() uint16 { + return uint16(0) +} + +// String is a rudimentary string representation of KeymapNotifyEvent. +func (v KeymapNotifyEvent) String() string { + fieldVals := make([]string, 0, 1) + return "KeymapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[11] = KeymapNotifyEventNew +} + +type Keysym uint32 + +const ( + KillAllTemporary = 0 +) + +// LeaveNotify is the event number for a LeaveNotifyEvent. +const LeaveNotify = 8 + +type LeaveNotifyEvent EnterNotifyEvent + +// LeaveNotifyEventNew constructs a LeaveNotifyEvent value that implements xgb.Event from a byte slice. +func LeaveNotifyEventNew(buf []byte) xgb.Event { + return LeaveNotifyEvent(EnterNotifyEventNew(buf).(EnterNotifyEvent)) +} + +// Bytes writes a LeaveNotifyEvent value to a byte slice. +func (v LeaveNotifyEvent) Bytes() []byte { + buf := EnterNotifyEvent(v).Bytes() + buf[0] = 8 + return buf +} + +// SequenceId returns the sequence id attached to the LeaveNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v LeaveNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +func (v LeaveNotifyEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreenFocus: %d", v.SameScreenFocus)) + return "LeaveNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[8] = LeaveNotifyEventNew +} + +const ( + LedModeOff = 0 + LedModeOn = 1 +) + +// BadLength is the error number for a BadLength. +const BadLength = 16 + +type LengthError RequestError + +// LengthErrorNew constructs a LengthError value that implements xgb.Error from a byte slice. +func LengthErrorNew(buf []byte) xgb.Error { + v := LengthError(RequestErrorNew(buf).(RequestError)) + v.NiceName = "Length" + return v +} + +// SequenceId returns the sequence id attached to the BadLength error. +// This is mostly used internally. +func (err LengthError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadLength error. If no bad value exists, 0 is returned. +func (err LengthError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadLength error. +func (err LengthError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadLength {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[16] = LengthErrorNew +} + +const ( + LineStyleSolid = 0 + LineStyleOnOffDash = 1 + LineStyleDoubleDash = 2 +) + +const ( + MapIndexShift = 0 + MapIndexLock = 1 + MapIndexControl = 2 + MapIndex1 = 3 + MapIndex2 = 4 + MapIndex3 = 5 + MapIndex4 = 6 + MapIndex5 = 7 +) + +// MapNotify is the event number for a MapNotifyEvent. +const MapNotify = 19 + +type MapNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window + OverrideRedirect bool + // padding: 3 bytes +} + +// MapNotifyEventNew constructs a MapNotifyEvent value that implements xgb.Event from a byte slice. +func MapNotifyEventNew(buf []byte) xgb.Event { + v := MapNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.OverrideRedirect = true + } else { + v.OverrideRedirect = false + } + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a MapNotifyEvent value to a byte slice. +func (v MapNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 19 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + if v.OverrideRedirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the MapNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v MapNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of MapNotifyEvent. +func (v MapNotifyEvent) String() string { + fieldVals := make([]string, 0, 5) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect)) + return "MapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[19] = MapNotifyEventNew +} + +// MapRequest is the event number for a MapRequestEvent. +const MapRequest = 20 + +type MapRequestEvent struct { + Sequence uint16 + // padding: 1 bytes + Parent Window + Window Window +} + +// MapRequestEventNew constructs a MapRequestEvent value that implements xgb.Event from a byte slice. +func MapRequestEventNew(buf []byte) xgb.Event { + v := MapRequestEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Parent = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a MapRequestEvent value to a byte slice. +func (v MapRequestEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 20 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Parent)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the MapRequest event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v MapRequestEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of MapRequestEvent. +func (v MapRequestEvent) String() string { + fieldVals := make([]string, 0, 3) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + return "MapRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[20] = MapRequestEventNew +} + +const ( + MapStateUnmapped = 0 + MapStateUnviewable = 1 + MapStateViewable = 2 +) + +const ( + MappingModifier = 0 + MappingKeyboard = 1 + MappingPointer = 2 +) + +// MappingNotify is the event number for a MappingNotifyEvent. +const MappingNotify = 34 + +type MappingNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Request byte + FirstKeycode Keycode + Count byte + // padding: 1 bytes +} + +// MappingNotifyEventNew constructs a MappingNotifyEvent value that implements xgb.Event from a byte slice. +func MappingNotifyEventNew(buf []byte) xgb.Event { + v := MappingNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Request = buf[b] + b += 1 + + v.FirstKeycode = Keycode(buf[b]) + b += 1 + + v.Count = buf[b] + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a MappingNotifyEvent value to a byte slice. +func (v MappingNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 34 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + buf[b] = v.Request + b += 1 + + buf[b] = byte(v.FirstKeycode) + b += 1 + + buf[b] = v.Count + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the MappingNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v MappingNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of MappingNotifyEvent. +func (v MappingNotifyEvent) String() string { + fieldVals := make([]string, 0, 5) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Request: %d", v.Request)) + fieldVals = append(fieldVals, xgb.Sprintf("FirstKeycode: %d", v.FirstKeycode)) + fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count)) + return "MappingNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[34] = MappingNotifyEventNew +} + +const ( + MappingStatusSuccess = 0 + MappingStatusBusy = 1 + MappingStatusFailure = 2 +) + +// BadMatch is the error number for a BadMatch. +const BadMatch = 8 + +type MatchError RequestError + +// MatchErrorNew constructs a MatchError value that implements xgb.Error from a byte slice. +func MatchErrorNew(buf []byte) xgb.Error { + v := MatchError(RequestErrorNew(buf).(RequestError)) + v.NiceName = "Match" + return v +} + +// SequenceId returns the sequence id attached to the BadMatch error. +// This is mostly used internally. +func (err MatchError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadMatch error. If no bad value exists, 0 is returned. +func (err MatchError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadMatch error. +func (err MatchError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadMatch {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[8] = MatchErrorNew +} + +const ( + ModMaskShift = 1 + ModMaskLock = 2 + ModMaskControl = 4 + ModMask1 = 8 + ModMask2 = 16 + ModMask3 = 32 + ModMask4 = 64 + ModMask5 = 128 + ModMaskAny = 32768 +) + +const ( + MotionNormal = 0 + MotionHint = 1 +) + +// MotionNotify is the event number for a MotionNotifyEvent. +const MotionNotify = 6 + +type MotionNotifyEvent struct { + Sequence uint16 + Detail byte + Time Timestamp + Root Window + Event Window + Child Window + RootX int16 + RootY int16 + EventX int16 + EventY int16 + State uint16 + SameScreen bool + // padding: 1 bytes +} + +// MotionNotifyEventNew constructs a MotionNotifyEvent value that implements xgb.Event from a byte slice. +func MotionNotifyEventNew(buf []byte) xgb.Event { + v := MotionNotifyEvent{} + b := 1 // don't read event number + + v.Detail = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Child = Window(xgb.Get32(buf[b:])) + b += 4 + + v.RootX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RootY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.EventY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.State = xgb.Get16(buf[b:]) + b += 2 + + if buf[b] == 1 { + v.SameScreen = true + } else { + v.SameScreen = false + } + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a MotionNotifyEvent value to a byte slice. +func (v MotionNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 6 + b += 1 + + buf[b] = v.Detail + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Child)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.RootX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.RootY)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventX)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.EventY)) + b += 2 + + xgb.Put16(buf[b:], v.State) + b += 2 + + if v.SameScreen { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the MotionNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v MotionNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of MotionNotifyEvent. +func (v MotionNotifyEvent) String() string { + fieldVals := make([]string, 0, 12) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child)) + fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX)) + fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY)) + fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX)) + fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen)) + return "MotionNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[6] = MotionNotifyEventNew +} + +// BadName is the error number for a BadName. +const BadName = 15 + +type NameError RequestError + +// NameErrorNew constructs a NameError value that implements xgb.Error from a byte slice. +func NameErrorNew(buf []byte) xgb.Error { + v := NameError(RequestErrorNew(buf).(RequestError)) + v.NiceName = "Name" + return v +} + +// SequenceId returns the sequence id attached to the BadName error. +// This is mostly used internally. +func (err NameError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadName error. If no bad value exists, 0 is returned. +func (err NameError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadName error. +func (err NameError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadName {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[15] = NameErrorNew +} + +// NoExposure is the event number for a NoExposureEvent. +const NoExposure = 14 + +type NoExposureEvent struct { + Sequence uint16 + // padding: 1 bytes + Drawable Drawable + MinorOpcode uint16 + MajorOpcode byte + // padding: 1 bytes +} + +// NoExposureEventNew constructs a NoExposureEvent value that implements xgb.Event from a byte slice. +func NoExposureEventNew(buf []byte) xgb.Event { + v := NoExposureEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Drawable = Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.MinorOpcode = xgb.Get16(buf[b:]) + b += 2 + + v.MajorOpcode = buf[b] + b += 1 + + b += 1 // padding + + return v +} + +// Bytes writes a NoExposureEvent value to a byte slice. +func (v NoExposureEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 14 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put16(buf[b:], v.MinorOpcode) + b += 2 + + buf[b] = v.MajorOpcode + b += 1 + + b += 1 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the NoExposure event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v NoExposureEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of NoExposureEvent. +func (v NoExposureEvent) String() string { + fieldVals := make([]string, 0, 5) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", v.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", v.MajorOpcode)) + return "NoExposure {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[14] = NoExposureEventNew +} + +const ( + NotifyDetailAncestor = 0 + NotifyDetailVirtual = 1 + NotifyDetailInferior = 2 + NotifyDetailNonlinear = 3 + NotifyDetailNonlinearVirtual = 4 + NotifyDetailPointer = 5 + NotifyDetailPointerRoot = 6 + NotifyDetailNone = 7 +) + +const ( + NotifyModeNormal = 0 + NotifyModeGrab = 1 + NotifyModeUngrab = 2 + NotifyModeWhileGrabbed = 3 +) + +type Pixmap uint32 + +func NewPixmapId(c *xgb.Conn) (Pixmap, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Pixmap(id), nil +} + +// BadPixmap is the error number for a BadPixmap. +const BadPixmap = 4 + +type PixmapError ValueError + +// PixmapErrorNew constructs a PixmapError value that implements xgb.Error from a byte slice. +func PixmapErrorNew(buf []byte) xgb.Error { + v := PixmapError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Pixmap" + return v +} + +// SequenceId returns the sequence id attached to the BadPixmap error. +// This is mostly used internally. +func (err PixmapError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadPixmap error. If no bad value exists, 0 is returned. +func (err PixmapError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadPixmap error. +func (err PixmapError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadPixmap {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[4] = PixmapErrorNew +} + +const ( + PixmapNone = 0 +) + +const ( + PlaceOnTop = 0 + PlaceOnBottom = 1 +) + +type Point struct { + X int16 + Y int16 +} + +// PointRead reads a byte slice into a Point value. +func PointRead(buf []byte, v *Point) int { + b := 0 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + return b +} + +// PointReadList reads a byte slice into a list of Point values. +func PointReadList(buf []byte, dest []Point) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Point{} + b += PointRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Point value to a byte slice. +func (v Point) Bytes() []byte { + buf := make([]byte, 4) + b := 0 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + return buf[:b] +} + +// PointListBytes writes a list of Point values to a byte slice. +func PointListBytes(buf []byte, list []Point) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + PolyShapeComplex = 0 + PolyShapeNonconvex = 1 + PolyShapeConvex = 2 +) + +const ( + PropModeReplace = 0 + PropModePrepend = 1 + PropModeAppend = 2 +) + +const ( + PropertyNewValue = 0 + PropertyDelete = 1 +) + +// PropertyNotify is the event number for a PropertyNotifyEvent. +const PropertyNotify = 28 + +type PropertyNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Window Window + Atom Atom + Time Timestamp + State byte + // padding: 3 bytes +} + +// PropertyNotifyEventNew constructs a PropertyNotifyEvent value that implements xgb.Event from a byte slice. +func PropertyNotifyEventNew(buf []byte) xgb.Event { + v := PropertyNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Atom = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.State = buf[b] + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a PropertyNotifyEvent value to a byte slice. +func (v PropertyNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 28 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Atom)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + buf[b] = v.State + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the PropertyNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v PropertyNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of PropertyNotifyEvent. +func (v PropertyNotifyEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Atom: %d", v.Atom)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + return "PropertyNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[28] = PropertyNotifyEventNew +} + +const ( + QueryShapeOfLargestCursor = 0 + QueryShapeOfFastestTile = 1 + QueryShapeOfFastestStipple = 2 +) + +type Rectangle struct { + X int16 + Y int16 + Width uint16 + Height uint16 +} + +// RectangleRead reads a byte slice into a Rectangle value. +func RectangleRead(buf []byte, v *Rectangle) int { + b := 0 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + return b +} + +// RectangleReadList reads a byte slice into a list of Rectangle values. +func RectangleReadList(buf []byte, dest []Rectangle) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Rectangle{} + b += RectangleRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Rectangle value to a byte slice. +func (v Rectangle) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + return buf[:b] +} + +// RectangleListBytes writes a list of Rectangle values to a byte slice. +func RectangleListBytes(buf []byte, list []Rectangle) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ReparentNotify is the event number for a ReparentNotifyEvent. +const ReparentNotify = 21 + +type ReparentNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window + Parent Window + X int16 + Y int16 + OverrideRedirect bool + // padding: 3 bytes +} + +// ReparentNotifyEventNew constructs a ReparentNotifyEvent value that implements xgb.Event from a byte slice. +func ReparentNotifyEventNew(buf []byte) xgb.Event { + v := ReparentNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Parent = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + if buf[b] == 1 { + v.OverrideRedirect = true + } else { + v.OverrideRedirect = false + } + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a ReparentNotifyEvent value to a byte slice. +func (v ReparentNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 21 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Parent)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + if v.OverrideRedirect { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the ReparentNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ReparentNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ReparentNotifyEvent. +func (v ReparentNotifyEvent) String() string { + fieldVals := make([]string, 0, 8) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent)) + fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X)) + fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y)) + fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect)) + return "ReparentNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[21] = ReparentNotifyEventNew +} + +// BadRequest is the error number for a BadRequest. +const BadRequest = 1 + +type RequestError struct { + Sequence uint16 + NiceName string + BadValue uint32 + MinorOpcode uint16 + MajorOpcode byte + // padding: 1 bytes +} + +// RequestErrorNew constructs a RequestError value that implements xgb.Error from a byte slice. +func RequestErrorNew(buf []byte) xgb.Error { + v := RequestError{} + v.NiceName = "Request" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.BadValue = xgb.Get32(buf[b:]) + b += 4 + + v.MinorOpcode = xgb.Get16(buf[b:]) + b += 2 + + v.MajorOpcode = buf[b] + b += 1 + + b += 1 // padding + + return v +} + +// SequenceId returns the sequence id attached to the BadRequest error. +// This is mostly used internally. +func (err RequestError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadRequest error. If no bad value exists, 0 is returned. +func (err RequestError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadRequest error. + +func (err RequestError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[1] = RequestErrorNew +} + +// ResizeRequest is the event number for a ResizeRequestEvent. +const ResizeRequest = 25 + +type ResizeRequestEvent struct { + Sequence uint16 + // padding: 1 bytes + Window Window + Width uint16 + Height uint16 +} + +// ResizeRequestEventNew constructs a ResizeRequestEvent value that implements xgb.Event from a byte slice. +func ResizeRequestEventNew(buf []byte) xgb.Event { + v := ResizeRequestEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Bytes writes a ResizeRequestEvent value to a byte slice. +func (v ResizeRequestEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 25 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + return buf +} + +// SequenceId returns the sequence id attached to the ResizeRequest event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v ResizeRequestEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of ResizeRequestEvent. +func (v ResizeRequestEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width)) + fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height)) + return "ResizeRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[25] = ResizeRequestEventNew +} + +type Rgb struct { + Red uint16 + Green uint16 + Blue uint16 + // padding: 2 bytes +} + +// RgbRead reads a byte slice into a Rgb value. +func RgbRead(buf []byte, v *Rgb) int { + b := 0 + + v.Red = xgb.Get16(buf[b:]) + b += 2 + + v.Green = xgb.Get16(buf[b:]) + b += 2 + + v.Blue = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + return b +} + +// RgbReadList reads a byte slice into a list of Rgb values. +func RgbReadList(buf []byte, dest []Rgb) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Rgb{} + b += RgbRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Rgb value to a byte slice. +func (v Rgb) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], v.Red) + b += 2 + + xgb.Put16(buf[b:], v.Green) + b += 2 + + xgb.Put16(buf[b:], v.Blue) + b += 2 + + b += 2 // padding + + return buf[:b] +} + +// RgbListBytes writes a list of Rgb values to a byte slice. +func RgbListBytes(buf []byte, list []Rgb) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type ScreenInfo struct { + Root Window + DefaultColormap Colormap + WhitePixel uint32 + BlackPixel uint32 + CurrentInputMasks uint32 + WidthInPixels uint16 + HeightInPixels uint16 + WidthInMillimeters uint16 + HeightInMillimeters uint16 + MinInstalledMaps uint16 + MaxInstalledMaps uint16 + RootVisual Visualid + BackingStores byte + SaveUnders bool + RootDepth byte + AllowedDepthsLen byte + AllowedDepths []DepthInfo // size: DepthInfoListSize(AllowedDepths) +} + +// ScreenInfoRead reads a byte slice into a ScreenInfo value. +func ScreenInfoRead(buf []byte, v *ScreenInfo) int { + b := 0 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.DefaultColormap = Colormap(xgb.Get32(buf[b:])) + b += 4 + + v.WhitePixel = xgb.Get32(buf[b:]) + b += 4 + + v.BlackPixel = xgb.Get32(buf[b:]) + b += 4 + + v.CurrentInputMasks = xgb.Get32(buf[b:]) + b += 4 + + v.WidthInPixels = xgb.Get16(buf[b:]) + b += 2 + + v.HeightInPixels = xgb.Get16(buf[b:]) + b += 2 + + v.WidthInMillimeters = xgb.Get16(buf[b:]) + b += 2 + + v.HeightInMillimeters = xgb.Get16(buf[b:]) + b += 2 + + v.MinInstalledMaps = xgb.Get16(buf[b:]) + b += 2 + + v.MaxInstalledMaps = xgb.Get16(buf[b:]) + b += 2 + + v.RootVisual = Visualid(xgb.Get32(buf[b:])) + b += 4 + + v.BackingStores = buf[b] + b += 1 + + if buf[b] == 1 { + v.SaveUnders = true + } else { + v.SaveUnders = false + } + b += 1 + + v.RootDepth = buf[b] + b += 1 + + v.AllowedDepthsLen = buf[b] + b += 1 + + v.AllowedDepths = make([]DepthInfo, v.AllowedDepthsLen) + b += DepthInfoReadList(buf[b:], v.AllowedDepths) + + return b +} + +// ScreenInfoReadList reads a byte slice into a list of ScreenInfo values. +func ScreenInfoReadList(buf []byte, dest []ScreenInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ScreenInfo{} + b += ScreenInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ScreenInfo value to a byte slice. +func (v ScreenInfo) Bytes() []byte { + buf := make([]byte, (40 + DepthInfoListSize(v.AllowedDepths))) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Root)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.DefaultColormap)) + b += 4 + + xgb.Put32(buf[b:], v.WhitePixel) + b += 4 + + xgb.Put32(buf[b:], v.BlackPixel) + b += 4 + + xgb.Put32(buf[b:], v.CurrentInputMasks) + b += 4 + + xgb.Put16(buf[b:], v.WidthInPixels) + b += 2 + + xgb.Put16(buf[b:], v.HeightInPixels) + b += 2 + + xgb.Put16(buf[b:], v.WidthInMillimeters) + b += 2 + + xgb.Put16(buf[b:], v.HeightInMillimeters) + b += 2 + + xgb.Put16(buf[b:], v.MinInstalledMaps) + b += 2 + + xgb.Put16(buf[b:], v.MaxInstalledMaps) + b += 2 + + xgb.Put32(buf[b:], uint32(v.RootVisual)) + b += 4 + + buf[b] = v.BackingStores + b += 1 + + if v.SaveUnders { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + buf[b] = v.RootDepth + b += 1 + + buf[b] = v.AllowedDepthsLen + b += 1 + + b += DepthInfoListBytes(buf[b:], v.AllowedDepths) + + return buf[:b] +} + +// ScreenInfoListBytes writes a list of ScreenInfo values to a byte slice. +func ScreenInfoListBytes(buf []byte, list []ScreenInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ScreenInfoListSize computes the size (bytes) of a list of ScreenInfo values. +func ScreenInfoListSize(list []ScreenInfo) int { + size := 0 + for _, item := range list { + size += (40 + DepthInfoListSize(item.AllowedDepths)) + } + return size +} + +const ( + ScreenSaverReset = 0 + ScreenSaverActive = 1 +) + +type Segment struct { + X1 int16 + Y1 int16 + X2 int16 + Y2 int16 +} + +// SegmentRead reads a byte slice into a Segment value. +func SegmentRead(buf []byte, v *Segment) int { + b := 0 + + v.X1 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y1 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.X2 = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y2 = int16(xgb.Get16(buf[b:])) + b += 2 + + return b +} + +// SegmentReadList reads a byte slice into a list of Segment values. +func SegmentReadList(buf []byte, dest []Segment) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Segment{} + b += SegmentRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Segment value to a byte slice. +func (v Segment) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put16(buf[b:], uint16(v.X1)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y1)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.X2)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y2)) + b += 2 + + return buf[:b] +} + +// SegmentListBytes writes a list of Segment values to a byte slice. +func SegmentListBytes(buf []byte, list []Segment) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// SelectionClear is the event number for a SelectionClearEvent. +const SelectionClear = 29 + +type SelectionClearEvent struct { + Sequence uint16 + // padding: 1 bytes + Time Timestamp + Owner Window + Selection Atom +} + +// SelectionClearEventNew constructs a SelectionClearEvent value that implements xgb.Event from a byte slice. +func SelectionClearEventNew(buf []byte) xgb.Event { + v := SelectionClearEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Owner = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Selection = Atom(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a SelectionClearEvent value to a byte slice. +func (v SelectionClearEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 29 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Owner)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Selection)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the SelectionClear event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v SelectionClearEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of SelectionClearEvent. +func (v SelectionClearEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Owner: %d", v.Owner)) + fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection)) + return "SelectionClear {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[29] = SelectionClearEventNew +} + +// SelectionNotify is the event number for a SelectionNotifyEvent. +const SelectionNotify = 31 + +type SelectionNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Time Timestamp + Requestor Window + Selection Atom + Target Atom + Property Atom +} + +// SelectionNotifyEventNew constructs a SelectionNotifyEvent value that implements xgb.Event from a byte slice. +func SelectionNotifyEventNew(buf []byte) xgb.Event { + v := SelectionNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Requestor = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Selection = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Target = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Property = Atom(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a SelectionNotifyEvent value to a byte slice. +func (v SelectionNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 31 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Requestor)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Selection)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Target)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Property)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the SelectionNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v SelectionNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of SelectionNotifyEvent. +func (v SelectionNotifyEvent) String() string { + fieldVals := make([]string, 0, 6) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Requestor: %d", v.Requestor)) + fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection)) + fieldVals = append(fieldVals, xgb.Sprintf("Target: %d", v.Target)) + fieldVals = append(fieldVals, xgb.Sprintf("Property: %d", v.Property)) + return "SelectionNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[31] = SelectionNotifyEventNew +} + +// SelectionRequest is the event number for a SelectionRequestEvent. +const SelectionRequest = 30 + +type SelectionRequestEvent struct { + Sequence uint16 + // padding: 1 bytes + Time Timestamp + Owner Window + Requestor Window + Selection Atom + Target Atom + Property Atom +} + +// SelectionRequestEventNew constructs a SelectionRequestEvent value that implements xgb.Event from a byte slice. +func SelectionRequestEventNew(buf []byte) xgb.Event { + v := SelectionRequestEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Owner = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Requestor = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Selection = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Target = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Property = Atom(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a SelectionRequestEvent value to a byte slice. +func (v SelectionRequestEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 30 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Owner)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Requestor)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Selection)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Target)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Property)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the SelectionRequest event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v SelectionRequestEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of SelectionRequestEvent. +func (v SelectionRequestEvent) String() string { + fieldVals := make([]string, 0, 7) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Owner: %d", v.Owner)) + fieldVals = append(fieldVals, xgb.Sprintf("Requestor: %d", v.Requestor)) + fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection)) + fieldVals = append(fieldVals, xgb.Sprintf("Target: %d", v.Target)) + fieldVals = append(fieldVals, xgb.Sprintf("Property: %d", v.Property)) + return "SelectionRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[30] = SelectionRequestEventNew +} + +const ( + SendEventDestPointerWindow = 0 + SendEventDestItemFocus = 1 +) + +const ( + SetModeInsert = 0 + SetModeDelete = 1 +) + +type SetupAuthenticate struct { + Status byte + // padding: 5 bytes + Length uint16 + Reason string // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// SetupAuthenticateRead reads a byte slice into a SetupAuthenticate value. +func SetupAuthenticateRead(buf []byte, v *SetupAuthenticate) int { + b := 0 + + v.Status = buf[b] + b += 1 + + b += 5 // padding + + v.Length = xgb.Get16(buf[b:]) + b += 2 + + { + byteString := make([]byte, (int(v.Length) * 4)) + copy(byteString[:(int(v.Length)*4)], buf[b:]) + v.Reason = string(byteString) + b += int((int(v.Length) * 4)) + } + + return b +} + +// SetupAuthenticateReadList reads a byte slice into a list of SetupAuthenticate values. +func SetupAuthenticateReadList(buf []byte, dest []SetupAuthenticate) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = SetupAuthenticate{} + b += SetupAuthenticateRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a SetupAuthenticate value to a byte slice. +func (v SetupAuthenticate) Bytes() []byte { + buf := make([]byte, (8 + xgb.Pad(((int(v.Length) * 4) * 1)))) + b := 0 + + buf[b] = v.Status + b += 1 + + b += 5 // padding + + xgb.Put16(buf[b:], v.Length) + b += 2 + + copy(buf[b:], v.Reason[:(int(v.Length)*4)]) + b += int((int(v.Length) * 4)) + + return buf[:b] +} + +// SetupAuthenticateListBytes writes a list of SetupAuthenticate values to a byte slice. +func SetupAuthenticateListBytes(buf []byte, list []SetupAuthenticate) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// SetupAuthenticateListSize computes the size (bytes) of a list of SetupAuthenticate values. +func SetupAuthenticateListSize(list []SetupAuthenticate) int { + size := 0 + for _, item := range list { + size += (8 + xgb.Pad(((int(item.Length) * 4) * 1))) + } + return size +} + +type SetupFailed struct { + Status byte + ReasonLen byte + ProtocolMajorVersion uint16 + ProtocolMinorVersion uint16 + Length uint16 + Reason string // size: xgb.Pad((int(ReasonLen) * 1)) +} + +// SetupFailedRead reads a byte slice into a SetupFailed value. +func SetupFailedRead(buf []byte, v *SetupFailed) int { + b := 0 + + v.Status = buf[b] + b += 1 + + v.ReasonLen = buf[b] + b += 1 + + v.ProtocolMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ProtocolMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get16(buf[b:]) + b += 2 + + { + byteString := make([]byte, v.ReasonLen) + copy(byteString[:v.ReasonLen], buf[b:]) + v.Reason = string(byteString) + b += int(v.ReasonLen) + } + + return b +} + +// SetupFailedReadList reads a byte slice into a list of SetupFailed values. +func SetupFailedReadList(buf []byte, dest []SetupFailed) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = SetupFailed{} + b += SetupFailedRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a SetupFailed value to a byte slice. +func (v SetupFailed) Bytes() []byte { + buf := make([]byte, (8 + xgb.Pad((int(v.ReasonLen) * 1)))) + b := 0 + + buf[b] = v.Status + b += 1 + + buf[b] = v.ReasonLen + b += 1 + + xgb.Put16(buf[b:], v.ProtocolMajorVersion) + b += 2 + + xgb.Put16(buf[b:], v.ProtocolMinorVersion) + b += 2 + + xgb.Put16(buf[b:], v.Length) + b += 2 + + copy(buf[b:], v.Reason[:v.ReasonLen]) + b += int(v.ReasonLen) + + return buf[:b] +} + +// SetupFailedListBytes writes a list of SetupFailed values to a byte slice. +func SetupFailedListBytes(buf []byte, list []SetupFailed) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// SetupFailedListSize computes the size (bytes) of a list of SetupFailed values. +func SetupFailedListSize(list []SetupFailed) int { + size := 0 + for _, item := range list { + size += (8 + xgb.Pad((int(item.ReasonLen) * 1))) + } + return size +} + +type SetupInfo struct { + Status byte + // padding: 1 bytes + ProtocolMajorVersion uint16 + ProtocolMinorVersion uint16 + Length uint16 + ReleaseNumber uint32 + ResourceIdBase uint32 + ResourceIdMask uint32 + MotionBufferSize uint32 + VendorLen uint16 + MaximumRequestLength uint16 + RootsLen byte + PixmapFormatsLen byte + ImageByteOrder byte + BitmapFormatBitOrder byte + BitmapFormatScanlineUnit byte + BitmapFormatScanlinePad byte + MinKeycode Keycode + MaxKeycode Keycode + // padding: 4 bytes + Vendor string // size: xgb.Pad((int(VendorLen) * 1)) + // alignment gap to multiple of 4 + PixmapFormats []Format // size: xgb.Pad((int(PixmapFormatsLen) * 8)) + Roots []ScreenInfo // size: ScreenInfoListSize(Roots) +} + +// SetupInfoRead reads a byte slice into a SetupInfo value. +func SetupInfoRead(buf []byte, v *SetupInfo) int { + b := 0 + + v.Status = buf[b] + b += 1 + + b += 1 // padding + + v.ProtocolMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ProtocolMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get16(buf[b:]) + b += 2 + + v.ReleaseNumber = xgb.Get32(buf[b:]) + b += 4 + + v.ResourceIdBase = xgb.Get32(buf[b:]) + b += 4 + + v.ResourceIdMask = xgb.Get32(buf[b:]) + b += 4 + + v.MotionBufferSize = xgb.Get32(buf[b:]) + b += 4 + + v.VendorLen = xgb.Get16(buf[b:]) + b += 2 + + v.MaximumRequestLength = xgb.Get16(buf[b:]) + b += 2 + + v.RootsLen = buf[b] + b += 1 + + v.PixmapFormatsLen = buf[b] + b += 1 + + v.ImageByteOrder = buf[b] + b += 1 + + v.BitmapFormatBitOrder = buf[b] + b += 1 + + v.BitmapFormatScanlineUnit = buf[b] + b += 1 + + v.BitmapFormatScanlinePad = buf[b] + b += 1 + + v.MinKeycode = Keycode(buf[b]) + b += 1 + + v.MaxKeycode = Keycode(buf[b]) + b += 1 + + b += 4 // padding + + { + byteString := make([]byte, v.VendorLen) + copy(byteString[:v.VendorLen], buf[b:]) + v.Vendor = string(byteString) + b += int(v.VendorLen) + } + + b = (b + 3) & ^3 // alignment gap + + v.PixmapFormats = make([]Format, v.PixmapFormatsLen) + b += FormatReadList(buf[b:], v.PixmapFormats) + + v.Roots = make([]ScreenInfo, v.RootsLen) + b += ScreenInfoReadList(buf[b:], v.Roots) + + return b +} + +// SetupInfoReadList reads a byte slice into a list of SetupInfo values. +func SetupInfoReadList(buf []byte, dest []SetupInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = SetupInfo{} + b += SetupInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a SetupInfo value to a byte slice. +func (v SetupInfo) Bytes() []byte { + buf := make([]byte, ((((40 + xgb.Pad((int(v.VendorLen) * 1))) + 4) + xgb.Pad((int(v.PixmapFormatsLen) * 8))) + ScreenInfoListSize(v.Roots))) + b := 0 + + buf[b] = v.Status + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], v.ProtocolMajorVersion) + b += 2 + + xgb.Put16(buf[b:], v.ProtocolMinorVersion) + b += 2 + + xgb.Put16(buf[b:], v.Length) + b += 2 + + xgb.Put32(buf[b:], v.ReleaseNumber) + b += 4 + + xgb.Put32(buf[b:], v.ResourceIdBase) + b += 4 + + xgb.Put32(buf[b:], v.ResourceIdMask) + b += 4 + + xgb.Put32(buf[b:], v.MotionBufferSize) + b += 4 + + xgb.Put16(buf[b:], v.VendorLen) + b += 2 + + xgb.Put16(buf[b:], v.MaximumRequestLength) + b += 2 + + buf[b] = v.RootsLen + b += 1 + + buf[b] = v.PixmapFormatsLen + b += 1 + + buf[b] = v.ImageByteOrder + b += 1 + + buf[b] = v.BitmapFormatBitOrder + b += 1 + + buf[b] = v.BitmapFormatScanlineUnit + b += 1 + + buf[b] = v.BitmapFormatScanlinePad + b += 1 + + buf[b] = byte(v.MinKeycode) + b += 1 + + buf[b] = byte(v.MaxKeycode) + b += 1 + + b += 4 // padding + + copy(buf[b:], v.Vendor[:v.VendorLen]) + b += int(v.VendorLen) + + b = (b + 3) & ^3 // alignment gap + + b += FormatListBytes(buf[b:], v.PixmapFormats) + + b += ScreenInfoListBytes(buf[b:], v.Roots) + + return buf[:b] +} + +// SetupInfoListBytes writes a list of SetupInfo values to a byte slice. +func SetupInfoListBytes(buf []byte, list []SetupInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// SetupInfoListSize computes the size (bytes) of a list of SetupInfo values. +func SetupInfoListSize(list []SetupInfo) int { + size := 0 + for _, item := range list { + size += ((((40 + xgb.Pad((int(item.VendorLen) * 1))) + 4) + xgb.Pad((int(item.PixmapFormatsLen) * 8))) + ScreenInfoListSize(item.Roots)) + } + return size +} + +type SetupRequest struct { + ByteOrder byte + // padding: 1 bytes + ProtocolMajorVersion uint16 + ProtocolMinorVersion uint16 + AuthorizationProtocolNameLen uint16 + AuthorizationProtocolDataLen uint16 + // padding: 2 bytes + AuthorizationProtocolName string // size: xgb.Pad((int(AuthorizationProtocolNameLen) * 1)) + // alignment gap to multiple of 4 + AuthorizationProtocolData string // size: xgb.Pad((int(AuthorizationProtocolDataLen) * 1)) + // alignment gap to multiple of 4 +} + +// SetupRequestRead reads a byte slice into a SetupRequest value. +func SetupRequestRead(buf []byte, v *SetupRequest) int { + b := 0 + + v.ByteOrder = buf[b] + b += 1 + + b += 1 // padding + + v.ProtocolMajorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.ProtocolMinorVersion = xgb.Get16(buf[b:]) + b += 2 + + v.AuthorizationProtocolNameLen = xgb.Get16(buf[b:]) + b += 2 + + v.AuthorizationProtocolDataLen = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + { + byteString := make([]byte, v.AuthorizationProtocolNameLen) + copy(byteString[:v.AuthorizationProtocolNameLen], buf[b:]) + v.AuthorizationProtocolName = string(byteString) + b += int(v.AuthorizationProtocolNameLen) + } + + b = (b + 3) & ^3 // alignment gap + + { + byteString := make([]byte, v.AuthorizationProtocolDataLen) + copy(byteString[:v.AuthorizationProtocolDataLen], buf[b:]) + v.AuthorizationProtocolData = string(byteString) + b += int(v.AuthorizationProtocolDataLen) + } + + b = (b + 3) & ^3 // alignment gap + + return b +} + +// SetupRequestReadList reads a byte slice into a list of SetupRequest values. +func SetupRequestReadList(buf []byte, dest []SetupRequest) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = SetupRequest{} + b += SetupRequestRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a SetupRequest value to a byte slice. +func (v SetupRequest) Bytes() []byte { + buf := make([]byte, ((((12 + xgb.Pad((int(v.AuthorizationProtocolNameLen) * 1))) + 4) + xgb.Pad((int(v.AuthorizationProtocolDataLen) * 1))) + 4)) + b := 0 + + buf[b] = v.ByteOrder + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], v.ProtocolMajorVersion) + b += 2 + + xgb.Put16(buf[b:], v.ProtocolMinorVersion) + b += 2 + + xgb.Put16(buf[b:], v.AuthorizationProtocolNameLen) + b += 2 + + xgb.Put16(buf[b:], v.AuthorizationProtocolDataLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], v.AuthorizationProtocolName[:v.AuthorizationProtocolNameLen]) + b += int(v.AuthorizationProtocolNameLen) + + b = (b + 3) & ^3 // alignment gap + + copy(buf[b:], v.AuthorizationProtocolData[:v.AuthorizationProtocolDataLen]) + b += int(v.AuthorizationProtocolDataLen) + + b = (b + 3) & ^3 // alignment gap + + return buf[:b] +} + +// SetupRequestListBytes writes a list of SetupRequest values to a byte slice. +func SetupRequestListBytes(buf []byte, list []SetupRequest) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// SetupRequestListSize computes the size (bytes) of a list of SetupRequest values. +func SetupRequestListSize(list []SetupRequest) int { + size := 0 + for _, item := range list { + size += ((((12 + xgb.Pad((int(item.AuthorizationProtocolNameLen) * 1))) + 4) + xgb.Pad((int(item.AuthorizationProtocolDataLen) * 1))) + 4) + } + return size +} + +const ( + StackModeAbove = 0 + StackModeBelow = 1 + StackModeTopIf = 2 + StackModeBottomIf = 3 + StackModeOpposite = 4 +) + +type Str struct { + NameLen byte + Name string // size: xgb.Pad((int(NameLen) * 1)) +} + +// StrRead reads a byte slice into a Str value. +func StrRead(buf []byte, v *Str) int { + b := 0 + + v.NameLen = buf[b] + b += 1 + + { + byteString := make([]byte, v.NameLen) + copy(byteString[:v.NameLen], buf[b:]) + v.Name = string(byteString) + b += int(v.NameLen) + } + + return b +} + +// StrReadList reads a byte slice into a list of Str values. +func StrReadList(buf []byte, dest []Str) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Str{} + b += StrRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Str value to a byte slice. +func (v Str) Bytes() []byte { + buf := make([]byte, (1 + xgb.Pad((int(v.NameLen) * 1)))) + b := 0 + + buf[b] = v.NameLen + b += 1 + + copy(buf[b:], v.Name[:v.NameLen]) + b += int(v.NameLen) + + return buf[:b] +} + +// StrListBytes writes a list of Str values to a byte slice. +func StrListBytes(buf []byte, list []Str) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// StrListSize computes the size (bytes) of a list of Str values. +func StrListSize(list []Str) int { + size := 0 + for _, item := range list { + size += (1 + xgb.Pad((int(item.NameLen) * 1))) + } + return size +} + +const ( + SubwindowModeClipByChildren = 0 + SubwindowModeIncludeInferiors = 1 +) + +const ( + TimeCurrentTime = 0 +) + +type Timecoord struct { + Time Timestamp + X int16 + Y int16 +} + +// TimecoordRead reads a byte slice into a Timecoord value. +func TimecoordRead(buf []byte, v *Timecoord) int { + b := 0 + + v.Time = Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + return b +} + +// TimecoordReadList reads a byte slice into a list of Timecoord values. +func TimecoordReadList(buf []byte, dest []Timecoord) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Timecoord{} + b += TimecoordRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Timecoord value to a byte slice. +func (v Timecoord) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + return buf[:b] +} + +// TimecoordListBytes writes a list of Timecoord values to a byte slice. +func TimecoordListBytes(buf []byte, list []Timecoord) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Timestamp uint32 + +// UnmapNotify is the event number for a UnmapNotifyEvent. +const UnmapNotify = 18 + +type UnmapNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Event Window + Window Window + FromConfigure bool + // padding: 3 bytes +} + +// UnmapNotifyEventNew constructs a UnmapNotifyEvent value that implements xgb.Event from a byte slice. +func UnmapNotifyEventNew(buf []byte) xgb.Event { + v := UnmapNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Event = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.FromConfigure = true + } else { + v.FromConfigure = false + } + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a UnmapNotifyEvent value to a byte slice. +func (v UnmapNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 18 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Event)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + if v.FromConfigure { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the UnmapNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v UnmapNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of UnmapNotifyEvent. +func (v UnmapNotifyEvent) String() string { + fieldVals := make([]string, 0, 5) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("FromConfigure: %t", v.FromConfigure)) + return "UnmapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[18] = UnmapNotifyEventNew +} + +// BadValue is the error number for a BadValue. +const BadValue = 2 + +type ValueError struct { + Sequence uint16 + NiceName string + BadValue uint32 + MinorOpcode uint16 + MajorOpcode byte + // padding: 1 bytes +} + +// ValueErrorNew constructs a ValueError value that implements xgb.Error from a byte slice. +func ValueErrorNew(buf []byte) xgb.Error { + v := ValueError{} + v.NiceName = "Value" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.BadValue = xgb.Get32(buf[b:]) + b += 4 + + v.MinorOpcode = xgb.Get16(buf[b:]) + b += 2 + + v.MajorOpcode = buf[b] + b += 1 + + b += 1 // padding + + return v +} + +// SequenceId returns the sequence id attached to the BadValue error. +// This is mostly used internally. +func (err ValueError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadValue error. If no bad value exists, 0 is returned. +func (err ValueError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadValue error. + +func (err ValueError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadValue {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[2] = ValueErrorNew +} + +const ( + VisibilityUnobscured = 0 + VisibilityPartiallyObscured = 1 + VisibilityFullyObscured = 2 +) + +// VisibilityNotify is the event number for a VisibilityNotifyEvent. +const VisibilityNotify = 15 + +type VisibilityNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Window Window + State byte + // padding: 3 bytes +} + +// VisibilityNotifyEventNew constructs a VisibilityNotifyEvent value that implements xgb.Event from a byte slice. +func VisibilityNotifyEventNew(buf []byte) xgb.Event { + v := VisibilityNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Window = Window(xgb.Get32(buf[b:])) + b += 4 + + v.State = buf[b] + b += 1 + + b += 3 // padding + + return v +} + +// Bytes writes a VisibilityNotifyEvent value to a byte slice. +func (v VisibilityNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 15 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + buf[b] = v.State + b += 1 + + b += 3 // padding + + return buf +} + +// SequenceId returns the sequence id attached to the VisibilityNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v VisibilityNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of VisibilityNotifyEvent. +func (v VisibilityNotifyEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window)) + fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State)) + return "VisibilityNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewEventFuncs[15] = VisibilityNotifyEventNew +} + +const ( + VisualClassStaticGray = 0 + VisualClassGrayScale = 1 + VisualClassStaticColor = 2 + VisualClassPseudoColor = 3 + VisualClassTrueColor = 4 + VisualClassDirectColor = 5 +) + +type VisualInfo struct { + VisualId Visualid + Class byte + BitsPerRgbValue byte + ColormapEntries uint16 + RedMask uint32 + GreenMask uint32 + BlueMask uint32 + // padding: 4 bytes +} + +// VisualInfoRead reads a byte slice into a VisualInfo value. +func VisualInfoRead(buf []byte, v *VisualInfo) int { + b := 0 + + v.VisualId = Visualid(xgb.Get32(buf[b:])) + b += 4 + + v.Class = buf[b] + b += 1 + + v.BitsPerRgbValue = buf[b] + b += 1 + + v.ColormapEntries = xgb.Get16(buf[b:]) + b += 2 + + v.RedMask = xgb.Get32(buf[b:]) + b += 4 + + v.GreenMask = xgb.Get32(buf[b:]) + b += 4 + + v.BlueMask = xgb.Get32(buf[b:]) + b += 4 + + b += 4 // padding + + return b +} + +// VisualInfoReadList reads a byte slice into a list of VisualInfo values. +func VisualInfoReadList(buf []byte, dest []VisualInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = VisualInfo{} + b += VisualInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a VisualInfo value to a byte slice. +func (v VisualInfo) Bytes() []byte { + buf := make([]byte, 24) + b := 0 + + xgb.Put32(buf[b:], uint32(v.VisualId)) + b += 4 + + buf[b] = v.Class + b += 1 + + buf[b] = v.BitsPerRgbValue + b += 1 + + xgb.Put16(buf[b:], v.ColormapEntries) + b += 2 + + xgb.Put32(buf[b:], v.RedMask) + b += 4 + + xgb.Put32(buf[b:], v.GreenMask) + b += 4 + + xgb.Put32(buf[b:], v.BlueMask) + b += 4 + + b += 4 // padding + + return buf[:b] +} + +// VisualInfoListBytes writes a list of VisualInfo values to a byte slice. +func VisualInfoListBytes(buf []byte, list []VisualInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +type Visualid uint32 + +type Window uint32 + +func NewWindowId(c *xgb.Conn) (Window, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Window(id), nil +} + +const ( + WindowNone = 0 +) + +// BadWindow is the error number for a BadWindow. +const BadWindow = 3 + +type WindowError ValueError + +// WindowErrorNew constructs a WindowError value that implements xgb.Error from a byte slice. +func WindowErrorNew(buf []byte) xgb.Error { + v := WindowError(ValueErrorNew(buf).(ValueError)) + v.NiceName = "Window" + return v +} + +// SequenceId returns the sequence id attached to the BadWindow error. +// This is mostly used internally. +func (err WindowError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadWindow error. If no bad value exists, 0 is returned. +func (err WindowError) BadId() uint32 { + return err.BadValue +} + +// Error returns a rudimentary string representation of the BadWindow error. +func (err WindowError) Error() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue)) + fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode)) + fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode)) + return "BadWindow {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewErrorFuncs[3] = WindowErrorNew +} + +const ( + WindowClassCopyFromParent = 0 + WindowClassInputOutput = 1 + WindowClassInputOnly = 2 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// AllocColorCookie is a cookie used only for AllocColor requests. +type AllocColorCookie struct { + *xgb.Cookie +} + +// AllocColor sends a checked request. +// If an error occurs, it will be returned with the reply by calling AllocColorCookie.Reply() +func AllocColor(c *xgb.Conn, Cmap Colormap, Red uint16, Green uint16, Blue uint16) AllocColorCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(allocColorRequest(c, Cmap, Red, Green, Blue), cookie) + return AllocColorCookie{cookie} +} + +// AllocColorUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AllocColorUnchecked(c *xgb.Conn, Cmap Colormap, Red uint16, Green uint16, Blue uint16) AllocColorCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(allocColorRequest(c, Cmap, Red, Green, Blue), cookie) + return AllocColorCookie{cookie} +} + +// AllocColorReply represents the data returned from a AllocColor request. +type AllocColorReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Red uint16 + Green uint16 + Blue uint16 + // padding: 2 bytes + Pixel uint32 +} + +// Reply blocks and returns the reply data for a AllocColor request. +func (cook AllocColorCookie) Reply() (*AllocColorReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return allocColorReply(buf), nil +} + +// allocColorReply reads a byte slice into a AllocColorReply value. +func allocColorReply(buf []byte) *AllocColorReply { + v := new(AllocColorReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Red = xgb.Get16(buf[b:]) + b += 2 + + v.Green = xgb.Get16(buf[b:]) + b += 2 + + v.Blue = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Pixel = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for AllocColor +// allocColorRequest writes a AllocColor request to a byte slice. +func allocColorRequest(c *xgb.Conn, Cmap Colormap, Red uint16, Green uint16, Blue uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 84 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put16(buf[b:], Red) + b += 2 + + xgb.Put16(buf[b:], Green) + b += 2 + + xgb.Put16(buf[b:], Blue) + b += 2 + + b += 2 // padding + + return buf +} + +// AllocColorCellsCookie is a cookie used only for AllocColorCells requests. +type AllocColorCellsCookie struct { + *xgb.Cookie +} + +// AllocColorCells sends a checked request. +// If an error occurs, it will be returned with the reply by calling AllocColorCellsCookie.Reply() +func AllocColorCells(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Planes uint16) AllocColorCellsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(allocColorCellsRequest(c, Contiguous, Cmap, Colors, Planes), cookie) + return AllocColorCellsCookie{cookie} +} + +// AllocColorCellsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AllocColorCellsUnchecked(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Planes uint16) AllocColorCellsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(allocColorCellsRequest(c, Contiguous, Cmap, Colors, Planes), cookie) + return AllocColorCellsCookie{cookie} +} + +// AllocColorCellsReply represents the data returned from a AllocColorCells request. +type AllocColorCellsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + PixelsLen uint16 + MasksLen uint16 + // padding: 20 bytes + Pixels []uint32 // size: xgb.Pad((int(PixelsLen) * 4)) + Masks []uint32 // size: xgb.Pad((int(MasksLen) * 4)) +} + +// Reply blocks and returns the reply data for a AllocColorCells request. +func (cook AllocColorCellsCookie) Reply() (*AllocColorCellsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return allocColorCellsReply(buf), nil +} + +// allocColorCellsReply reads a byte slice into a AllocColorCellsReply value. +func allocColorCellsReply(buf []byte) *AllocColorCellsReply { + v := new(AllocColorCellsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PixelsLen = xgb.Get16(buf[b:]) + b += 2 + + v.MasksLen = xgb.Get16(buf[b:]) + b += 2 + + b += 20 // padding + + v.Pixels = make([]uint32, v.PixelsLen) + for i := 0; i < int(v.PixelsLen); i++ { + v.Pixels[i] = xgb.Get32(buf[b:]) + b += 4 + } + + v.Masks = make([]uint32, v.MasksLen) + for i := 0; i < int(v.MasksLen); i++ { + v.Masks[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for AllocColorCells +// allocColorCellsRequest writes a AllocColorCells request to a byte slice. +func allocColorCellsRequest(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Planes uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 86 // request opcode + b += 1 + + if Contiguous { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put16(buf[b:], Colors) + b += 2 + + xgb.Put16(buf[b:], Planes) + b += 2 + + return buf +} + +// AllocColorPlanesCookie is a cookie used only for AllocColorPlanes requests. +type AllocColorPlanesCookie struct { + *xgb.Cookie +} + +// AllocColorPlanes sends a checked request. +// If an error occurs, it will be returned with the reply by calling AllocColorPlanesCookie.Reply() +func AllocColorPlanes(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Reds uint16, Greens uint16, Blues uint16) AllocColorPlanesCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(allocColorPlanesRequest(c, Contiguous, Cmap, Colors, Reds, Greens, Blues), cookie) + return AllocColorPlanesCookie{cookie} +} + +// AllocColorPlanesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AllocColorPlanesUnchecked(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Reds uint16, Greens uint16, Blues uint16) AllocColorPlanesCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(allocColorPlanesRequest(c, Contiguous, Cmap, Colors, Reds, Greens, Blues), cookie) + return AllocColorPlanesCookie{cookie} +} + +// AllocColorPlanesReply represents the data returned from a AllocColorPlanes request. +type AllocColorPlanesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + PixelsLen uint16 + // padding: 2 bytes + RedMask uint32 + GreenMask uint32 + BlueMask uint32 + // padding: 8 bytes + Pixels []uint32 // size: xgb.Pad((int(PixelsLen) * 4)) +} + +// Reply blocks and returns the reply data for a AllocColorPlanes request. +func (cook AllocColorPlanesCookie) Reply() (*AllocColorPlanesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return allocColorPlanesReply(buf), nil +} + +// allocColorPlanesReply reads a byte slice into a AllocColorPlanesReply value. +func allocColorPlanesReply(buf []byte) *AllocColorPlanesReply { + v := new(AllocColorPlanesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PixelsLen = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.RedMask = xgb.Get32(buf[b:]) + b += 4 + + v.GreenMask = xgb.Get32(buf[b:]) + b += 4 + + v.BlueMask = xgb.Get32(buf[b:]) + b += 4 + + b += 8 // padding + + v.Pixels = make([]uint32, v.PixelsLen) + for i := 0; i < int(v.PixelsLen); i++ { + v.Pixels[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for AllocColorPlanes +// allocColorPlanesRequest writes a AllocColorPlanes request to a byte slice. +func allocColorPlanesRequest(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Reds uint16, Greens uint16, Blues uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 87 // request opcode + b += 1 + + if Contiguous { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put16(buf[b:], Colors) + b += 2 + + xgb.Put16(buf[b:], Reds) + b += 2 + + xgb.Put16(buf[b:], Greens) + b += 2 + + xgb.Put16(buf[b:], Blues) + b += 2 + + return buf +} + +// AllocNamedColorCookie is a cookie used only for AllocNamedColor requests. +type AllocNamedColorCookie struct { + *xgb.Cookie +} + +// AllocNamedColor sends a checked request. +// If an error occurs, it will be returned with the reply by calling AllocNamedColorCookie.Reply() +func AllocNamedColor(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) AllocNamedColorCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(allocNamedColorRequest(c, Cmap, NameLen, Name), cookie) + return AllocNamedColorCookie{cookie} +} + +// AllocNamedColorUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AllocNamedColorUnchecked(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) AllocNamedColorCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(allocNamedColorRequest(c, Cmap, NameLen, Name), cookie) + return AllocNamedColorCookie{cookie} +} + +// AllocNamedColorReply represents the data returned from a AllocNamedColor request. +type AllocNamedColorReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Pixel uint32 + ExactRed uint16 + ExactGreen uint16 + ExactBlue uint16 + VisualRed uint16 + VisualGreen uint16 + VisualBlue uint16 +} + +// Reply blocks and returns the reply data for a AllocNamedColor request. +func (cook AllocNamedColorCookie) Reply() (*AllocNamedColorReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return allocNamedColorReply(buf), nil +} + +// allocNamedColorReply reads a byte slice into a AllocNamedColorReply value. +func allocNamedColorReply(buf []byte) *AllocNamedColorReply { + v := new(AllocNamedColorReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Pixel = xgb.Get32(buf[b:]) + b += 4 + + v.ExactRed = xgb.Get16(buf[b:]) + b += 2 + + v.ExactGreen = xgb.Get16(buf[b:]) + b += 2 + + v.ExactBlue = xgb.Get16(buf[b:]) + b += 2 + + v.VisualRed = xgb.Get16(buf[b:]) + b += 2 + + v.VisualGreen = xgb.Get16(buf[b:]) + b += 2 + + v.VisualBlue = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for AllocNamedColor +// allocNamedColorRequest writes a AllocNamedColor request to a byte slice. +func allocNamedColorRequest(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) []byte { + size := xgb.Pad((12 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 85 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put16(buf[b:], NameLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:NameLen]) + b += int(NameLen) + + return buf +} + +// AllowEventsCookie is a cookie used only for AllowEvents requests. +type AllowEventsCookie struct { + *xgb.Cookie +} + +// AllowEvents sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AllowEvents(c *xgb.Conn, Mode byte, Time Timestamp) AllowEventsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(allowEventsRequest(c, Mode, Time), cookie) + return AllowEventsCookie{cookie} +} + +// AllowEventsChecked sends a checked request. +// If an error occurs, it can be retrieved using AllowEventsCookie.Check() +func AllowEventsChecked(c *xgb.Conn, Mode byte, Time Timestamp) AllowEventsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(allowEventsRequest(c, Mode, Time), cookie) + return AllowEventsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook AllowEventsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for AllowEvents +// allowEventsRequest writes a AllowEvents request to a byte slice. +func allowEventsRequest(c *xgb.Conn, Mode byte, Time Timestamp) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 35 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// BellCookie is a cookie used only for Bell requests. +type BellCookie struct { + *xgb.Cookie +} + +// Bell sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func Bell(c *xgb.Conn, Percent int8) BellCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(bellRequest(c, Percent), cookie) + return BellCookie{cookie} +} + +// BellChecked sends a checked request. +// If an error occurs, it can be retrieved using BellCookie.Check() +func BellChecked(c *xgb.Conn, Percent int8) BellCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(bellRequest(c, Percent), cookie) + return BellCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook BellCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for Bell +// bellRequest writes a Bell request to a byte slice. +func bellRequest(c *xgb.Conn, Percent int8) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 104 // request opcode + b += 1 + + buf[b] = byte(Percent) + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// ChangeActivePointerGrabCookie is a cookie used only for ChangeActivePointerGrab requests. +type ChangeActivePointerGrabCookie struct { + *xgb.Cookie +} + +// ChangeActivePointerGrab sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeActivePointerGrab(c *xgb.Conn, Cursor Cursor, Time Timestamp, EventMask uint16) ChangeActivePointerGrabCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeActivePointerGrabRequest(c, Cursor, Time, EventMask), cookie) + return ChangeActivePointerGrabCookie{cookie} +} + +// ChangeActivePointerGrabChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeActivePointerGrabCookie.Check() +func ChangeActivePointerGrabChecked(c *xgb.Conn, Cursor Cursor, Time Timestamp, EventMask uint16) ChangeActivePointerGrabCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeActivePointerGrabRequest(c, Cursor, Time, EventMask), cookie) + return ChangeActivePointerGrabCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeActivePointerGrabCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeActivePointerGrab +// changeActivePointerGrabRequest writes a ChangeActivePointerGrab request to a byte slice. +func changeActivePointerGrabRequest(c *xgb.Conn, Cursor Cursor, Time Timestamp, EventMask uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 30 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + xgb.Put16(buf[b:], EventMask) + b += 2 + + b += 2 // padding + + return buf +} + +// ChangeGCCookie is a cookie used only for ChangeGC requests. +type ChangeGCCookie struct { + *xgb.Cookie +} + +// ChangeGC sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeGC(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) ChangeGCCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeGCRequest(c, Gc, ValueMask, ValueList), cookie) + return ChangeGCCookie{cookie} +} + +// ChangeGCChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeGCCookie.Check() +func ChangeGCChecked(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) ChangeGCCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeGCRequest(c, Gc, ValueMask, ValueList), cookie) + return ChangeGCCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeGCCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeGC +// changeGCRequest writes a ChangeGC request to a byte slice. +func changeGCRequest(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + buf[b] = 56 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// ChangeHostsCookie is a cookie used only for ChangeHosts requests. +type ChangeHostsCookie struct { + *xgb.Cookie +} + +// ChangeHosts sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeHosts(c *xgb.Conn, Mode byte, Family byte, AddressLen uint16, Address []byte) ChangeHostsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeHostsRequest(c, Mode, Family, AddressLen, Address), cookie) + return ChangeHostsCookie{cookie} +} + +// ChangeHostsChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeHostsCookie.Check() +func ChangeHostsChecked(c *xgb.Conn, Mode byte, Family byte, AddressLen uint16, Address []byte) ChangeHostsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeHostsRequest(c, Mode, Family, AddressLen, Address), cookie) + return ChangeHostsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeHostsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeHosts +// changeHostsRequest writes a ChangeHosts request to a byte slice. +func changeHostsRequest(c *xgb.Conn, Mode byte, Family byte, AddressLen uint16, Address []byte) []byte { + size := xgb.Pad((8 + xgb.Pad((int(AddressLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 109 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Family + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], AddressLen) + b += 2 + + copy(buf[b:], Address[:AddressLen]) + b += int(AddressLen) + + return buf +} + +// ChangeKeyboardControlCookie is a cookie used only for ChangeKeyboardControl requests. +type ChangeKeyboardControlCookie struct { + *xgb.Cookie +} + +// ChangeKeyboardControl sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeKeyboardControl(c *xgb.Conn, ValueMask uint32, ValueList []uint32) ChangeKeyboardControlCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeKeyboardControlRequest(c, ValueMask, ValueList), cookie) + return ChangeKeyboardControlCookie{cookie} +} + +// ChangeKeyboardControlChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeKeyboardControlCookie.Check() +func ChangeKeyboardControlChecked(c *xgb.Conn, ValueMask uint32, ValueList []uint32) ChangeKeyboardControlCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeKeyboardControlRequest(c, ValueMask, ValueList), cookie) + return ChangeKeyboardControlCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeKeyboardControlCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeKeyboardControl +// changeKeyboardControlRequest writes a ChangeKeyboardControl request to a byte slice. +func changeKeyboardControlRequest(c *xgb.Conn, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((8 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + buf[b] = 102 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// ChangeKeyboardMappingCookie is a cookie used only for ChangeKeyboardMapping requests. +type ChangeKeyboardMappingCookie struct { + *xgb.Cookie +} + +// ChangeKeyboardMapping sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeKeyboardMapping(c *xgb.Conn, KeycodeCount byte, FirstKeycode Keycode, KeysymsPerKeycode byte, Keysyms []Keysym) ChangeKeyboardMappingCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeKeyboardMappingRequest(c, KeycodeCount, FirstKeycode, KeysymsPerKeycode, Keysyms), cookie) + return ChangeKeyboardMappingCookie{cookie} +} + +// ChangeKeyboardMappingChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeKeyboardMappingCookie.Check() +func ChangeKeyboardMappingChecked(c *xgb.Conn, KeycodeCount byte, FirstKeycode Keycode, KeysymsPerKeycode byte, Keysyms []Keysym) ChangeKeyboardMappingCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeKeyboardMappingRequest(c, KeycodeCount, FirstKeycode, KeysymsPerKeycode, Keysyms), cookie) + return ChangeKeyboardMappingCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeKeyboardMappingCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeKeyboardMapping +// changeKeyboardMappingRequest writes a ChangeKeyboardMapping request to a byte slice. +func changeKeyboardMappingRequest(c *xgb.Conn, KeycodeCount byte, FirstKeycode Keycode, KeysymsPerKeycode byte, Keysyms []Keysym) []byte { + size := xgb.Pad((8 + xgb.Pad(((int(KeycodeCount) * int(KeysymsPerKeycode)) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 100 // request opcode + b += 1 + + buf[b] = KeycodeCount + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = byte(FirstKeycode) + b += 1 + + buf[b] = KeysymsPerKeycode + b += 1 + + b += 2 // padding + + for i := 0; i < int((int(KeycodeCount) * int(KeysymsPerKeycode))); i++ { + xgb.Put32(buf[b:], uint32(Keysyms[i])) + b += 4 + } + + return buf +} + +// ChangePointerControlCookie is a cookie used only for ChangePointerControl requests. +type ChangePointerControlCookie struct { + *xgb.Cookie +} + +// ChangePointerControl sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangePointerControl(c *xgb.Conn, AccelerationNumerator int16, AccelerationDenominator int16, Threshold int16, DoAcceleration bool, DoThreshold bool) ChangePointerControlCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changePointerControlRequest(c, AccelerationNumerator, AccelerationDenominator, Threshold, DoAcceleration, DoThreshold), cookie) + return ChangePointerControlCookie{cookie} +} + +// ChangePointerControlChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangePointerControlCookie.Check() +func ChangePointerControlChecked(c *xgb.Conn, AccelerationNumerator int16, AccelerationDenominator int16, Threshold int16, DoAcceleration bool, DoThreshold bool) ChangePointerControlCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changePointerControlRequest(c, AccelerationNumerator, AccelerationDenominator, Threshold, DoAcceleration, DoThreshold), cookie) + return ChangePointerControlCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangePointerControlCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangePointerControl +// changePointerControlRequest writes a ChangePointerControl request to a byte slice. +func changePointerControlRequest(c *xgb.Conn, AccelerationNumerator int16, AccelerationDenominator int16, Threshold int16, DoAcceleration bool, DoThreshold bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 105 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], uint16(AccelerationNumerator)) + b += 2 + + xgb.Put16(buf[b:], uint16(AccelerationDenominator)) + b += 2 + + xgb.Put16(buf[b:], uint16(Threshold)) + b += 2 + + if DoAcceleration { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if DoThreshold { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + +// ChangePropertyCookie is a cookie used only for ChangeProperty requests. +type ChangePropertyCookie struct { + *xgb.Cookie +} + +// ChangeProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeProperty(c *xgb.Conn, Mode byte, Window Window, Property Atom, Type Atom, Format byte, DataLen uint32, Data []byte) ChangePropertyCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changePropertyRequest(c, Mode, Window, Property, Type, Format, DataLen, Data), cookie) + return ChangePropertyCookie{cookie} +} + +// ChangePropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangePropertyCookie.Check() +func ChangePropertyChecked(c *xgb.Conn, Mode byte, Window Window, Property Atom, Type Atom, Format byte, DataLen uint32, Data []byte) ChangePropertyCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changePropertyRequest(c, Mode, Window, Property, Type, Format, DataLen, Data), cookie) + return ChangePropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangePropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeProperty +// changePropertyRequest writes a ChangeProperty request to a byte slice. +func changePropertyRequest(c *xgb.Conn, Mode byte, Window Window, Property Atom, Type Atom, Format byte, DataLen uint32, Data []byte) []byte { + size := xgb.Pad((24 + xgb.Pad((((int(DataLen) * int(Format)) / 8) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 18 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + buf[b] = Format + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], DataLen) + b += 4 + + copy(buf[b:], Data[:((int(DataLen)*int(Format))/8)]) + b += int(((int(DataLen) * int(Format)) / 8)) + + return buf +} + +// ChangeSaveSetCookie is a cookie used only for ChangeSaveSet requests. +type ChangeSaveSetCookie struct { + *xgb.Cookie +} + +// ChangeSaveSet sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeSaveSet(c *xgb.Conn, Mode byte, Window Window) ChangeSaveSetCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeSaveSetRequest(c, Mode, Window), cookie) + return ChangeSaveSetCookie{cookie} +} + +// ChangeSaveSetChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeSaveSetCookie.Check() +func ChangeSaveSetChecked(c *xgb.Conn, Mode byte, Window Window) ChangeSaveSetCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeSaveSetRequest(c, Mode, Window), cookie) + return ChangeSaveSetCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeSaveSetCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeSaveSet +// changeSaveSetRequest writes a ChangeSaveSet request to a byte slice. +func changeSaveSetRequest(c *xgb.Conn, Mode byte, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 6 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// ChangeWindowAttributesCookie is a cookie used only for ChangeWindowAttributes requests. +type ChangeWindowAttributesCookie struct { + *xgb.Cookie +} + +// ChangeWindowAttributes sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ChangeWindowAttributes(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) ChangeWindowAttributesCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(changeWindowAttributesRequest(c, Window, ValueMask, ValueList), cookie) + return ChangeWindowAttributesCookie{cookie} +} + +// ChangeWindowAttributesChecked sends a checked request. +// If an error occurs, it can be retrieved using ChangeWindowAttributesCookie.Check() +func ChangeWindowAttributesChecked(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) ChangeWindowAttributesCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(changeWindowAttributesRequest(c, Window, ValueMask, ValueList), cookie) + return ChangeWindowAttributesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ChangeWindowAttributesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ChangeWindowAttributes +// changeWindowAttributesRequest writes a ChangeWindowAttributes request to a byte slice. +func changeWindowAttributesRequest(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + buf[b] = 2 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// CirculateWindowCookie is a cookie used only for CirculateWindow requests. +type CirculateWindowCookie struct { + *xgb.Cookie +} + +// CirculateWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CirculateWindow(c *xgb.Conn, Direction byte, Window Window) CirculateWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(circulateWindowRequest(c, Direction, Window), cookie) + return CirculateWindowCookie{cookie} +} + +// CirculateWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using CirculateWindowCookie.Check() +func CirculateWindowChecked(c *xgb.Conn, Direction byte, Window Window) CirculateWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(circulateWindowRequest(c, Direction, Window), cookie) + return CirculateWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CirculateWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CirculateWindow +// circulateWindowRequest writes a CirculateWindow request to a byte slice. +func circulateWindowRequest(c *xgb.Conn, Direction byte, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 13 // request opcode + b += 1 + + buf[b] = Direction + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// ClearAreaCookie is a cookie used only for ClearArea requests. +type ClearAreaCookie struct { + *xgb.Cookie +} + +// ClearArea sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ClearArea(c *xgb.Conn, Exposures bool, Window Window, X int16, Y int16, Width uint16, Height uint16) ClearAreaCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(clearAreaRequest(c, Exposures, Window, X, Y, Width, Height), cookie) + return ClearAreaCookie{cookie} +} + +// ClearAreaChecked sends a checked request. +// If an error occurs, it can be retrieved using ClearAreaCookie.Check() +func ClearAreaChecked(c *xgb.Conn, Exposures bool, Window Window, X int16, Y int16, Width uint16, Height uint16) ClearAreaCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(clearAreaRequest(c, Exposures, Window, X, Y, Width, Height), cookie) + return ClearAreaCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ClearAreaCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ClearArea +// clearAreaRequest writes a ClearArea request to a byte slice. +func clearAreaRequest(c *xgb.Conn, Exposures bool, Window Window, X int16, Y int16, Width uint16, Height uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 61 // request opcode + b += 1 + + if Exposures { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// CloseFontCookie is a cookie used only for CloseFont requests. +type CloseFontCookie struct { + *xgb.Cookie +} + +// CloseFont sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CloseFont(c *xgb.Conn, Font Font) CloseFontCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(closeFontRequest(c, Font), cookie) + return CloseFontCookie{cookie} +} + +// CloseFontChecked sends a checked request. +// If an error occurs, it can be retrieved using CloseFontCookie.Check() +func CloseFontChecked(c *xgb.Conn, Font Font) CloseFontCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(closeFontRequest(c, Font), cookie) + return CloseFontCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CloseFontCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CloseFont +// closeFontRequest writes a CloseFont request to a byte slice. +func closeFontRequest(c *xgb.Conn, Font Font) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 46 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Font)) + b += 4 + + return buf +} + +// ConfigureWindowCookie is a cookie used only for ConfigureWindow requests. +type ConfigureWindowCookie struct { + *xgb.Cookie +} + +// ConfigureWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ConfigureWindow(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) ConfigureWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(configureWindowRequest(c, Window, ValueMask, ValueList), cookie) + return ConfigureWindowCookie{cookie} +} + +// ConfigureWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using ConfigureWindowCookie.Check() +func ConfigureWindowChecked(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) ConfigureWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(configureWindowRequest(c, Window, ValueMask, ValueList), cookie) + return ConfigureWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ConfigureWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ConfigureWindow +// configureWindowRequest writes a ConfigureWindow request to a byte slice. +func configureWindowRequest(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + buf[b] = 12 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put16(buf[b:], ValueMask) + b += 2 + + b += 2 // padding + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// ConvertSelectionCookie is a cookie used only for ConvertSelection requests. +type ConvertSelectionCookie struct { + *xgb.Cookie +} + +// ConvertSelection sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ConvertSelection(c *xgb.Conn, Requestor Window, Selection Atom, Target Atom, Property Atom, Time Timestamp) ConvertSelectionCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(convertSelectionRequest(c, Requestor, Selection, Target, Property, Time), cookie) + return ConvertSelectionCookie{cookie} +} + +// ConvertSelectionChecked sends a checked request. +// If an error occurs, it can be retrieved using ConvertSelectionCookie.Check() +func ConvertSelectionChecked(c *xgb.Conn, Requestor Window, Selection Atom, Target Atom, Property Atom, Time Timestamp) ConvertSelectionCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(convertSelectionRequest(c, Requestor, Selection, Target, Property, Time), cookie) + return ConvertSelectionCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ConvertSelectionCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ConvertSelection +// convertSelectionRequest writes a ConvertSelection request to a byte slice. +func convertSelectionRequest(c *xgb.Conn, Requestor Window, Selection Atom, Target Atom, Property Atom, Time Timestamp) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + buf[b] = 24 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Requestor)) + b += 4 + + xgb.Put32(buf[b:], uint32(Selection)) + b += 4 + + xgb.Put32(buf[b:], uint32(Target)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// CopyAreaCookie is a cookie used only for CopyArea requests. +type CopyAreaCookie struct { + *xgb.Cookie +} + +// CopyArea sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyArea(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16) CopyAreaCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(copyAreaRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height), cookie) + return CopyAreaCookie{cookie} +} + +// CopyAreaChecked sends a checked request. +// If an error occurs, it can be retrieved using CopyAreaCookie.Check() +func CopyAreaChecked(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16) CopyAreaCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(copyAreaRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height), cookie) + return CopyAreaCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CopyAreaCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CopyArea +// copyAreaRequest writes a CopyArea request to a byte slice. +func copyAreaRequest(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16) []byte { + size := 28 + b := 0 + buf := make([]byte, size) + + buf[b] = 62 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SrcDrawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(DstDrawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstY)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// CopyColormapAndFreeCookie is a cookie used only for CopyColormapAndFree requests. +type CopyColormapAndFreeCookie struct { + *xgb.Cookie +} + +// CopyColormapAndFree sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyColormapAndFree(c *xgb.Conn, Mid Colormap, SrcCmap Colormap) CopyColormapAndFreeCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(copyColormapAndFreeRequest(c, Mid, SrcCmap), cookie) + return CopyColormapAndFreeCookie{cookie} +} + +// CopyColormapAndFreeChecked sends a checked request. +// If an error occurs, it can be retrieved using CopyColormapAndFreeCookie.Check() +func CopyColormapAndFreeChecked(c *xgb.Conn, Mid Colormap, SrcCmap Colormap) CopyColormapAndFreeCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(copyColormapAndFreeRequest(c, Mid, SrcCmap), cookie) + return CopyColormapAndFreeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CopyColormapAndFreeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CopyColormapAndFree +// copyColormapAndFreeRequest writes a CopyColormapAndFree request to a byte slice. +func copyColormapAndFreeRequest(c *xgb.Conn, Mid Colormap, SrcCmap Colormap) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 80 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Mid)) + b += 4 + + xgb.Put32(buf[b:], uint32(SrcCmap)) + b += 4 + + return buf +} + +// CopyGCCookie is a cookie used only for CopyGC requests. +type CopyGCCookie struct { + *xgb.Cookie +} + +// CopyGC sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyGC(c *xgb.Conn, SrcGc Gcontext, DstGc Gcontext, ValueMask uint32) CopyGCCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(copyGCRequest(c, SrcGc, DstGc, ValueMask), cookie) + return CopyGCCookie{cookie} +} + +// CopyGCChecked sends a checked request. +// If an error occurs, it can be retrieved using CopyGCCookie.Check() +func CopyGCChecked(c *xgb.Conn, SrcGc Gcontext, DstGc Gcontext, ValueMask uint32) CopyGCCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(copyGCRequest(c, SrcGc, DstGc, ValueMask), cookie) + return CopyGCCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CopyGCCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CopyGC +// copyGCRequest writes a CopyGC request to a byte slice. +func copyGCRequest(c *xgb.Conn, SrcGc Gcontext, DstGc Gcontext, ValueMask uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 57 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SrcGc)) + b += 4 + + xgb.Put32(buf[b:], uint32(DstGc)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + return buf +} + +// CopyPlaneCookie is a cookie used only for CopyPlane requests. +type CopyPlaneCookie struct { + *xgb.Cookie +} + +// CopyPlane sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyPlane(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16, BitPlane uint32) CopyPlaneCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(copyPlaneRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height, BitPlane), cookie) + return CopyPlaneCookie{cookie} +} + +// CopyPlaneChecked sends a checked request. +// If an error occurs, it can be retrieved using CopyPlaneCookie.Check() +func CopyPlaneChecked(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16, BitPlane uint32) CopyPlaneCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(copyPlaneRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height, BitPlane), cookie) + return CopyPlaneCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CopyPlaneCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CopyPlane +// copyPlaneRequest writes a CopyPlane request to a byte slice. +func copyPlaneRequest(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16, BitPlane uint32) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + buf[b] = 63 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SrcDrawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(DstDrawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstY)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put32(buf[b:], BitPlane) + b += 4 + + return buf +} + +// CreateColormapCookie is a cookie used only for CreateColormap requests. +type CreateColormapCookie struct { + *xgb.Cookie +} + +// CreateColormap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateColormap(c *xgb.Conn, Alloc byte, Mid Colormap, Window Window, Visual Visualid) CreateColormapCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(createColormapRequest(c, Alloc, Mid, Window, Visual), cookie) + return CreateColormapCookie{cookie} +} + +// CreateColormapChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateColormapCookie.Check() +func CreateColormapChecked(c *xgb.Conn, Alloc byte, Mid Colormap, Window Window, Visual Visualid) CreateColormapCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(createColormapRequest(c, Alloc, Mid, Window, Visual), cookie) + return CreateColormapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateColormapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateColormap +// createColormapRequest writes a CreateColormap request to a byte slice. +func createColormapRequest(c *xgb.Conn, Alloc byte, Mid Colormap, Window Window, Visual Visualid) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 78 // request opcode + b += 1 + + buf[b] = Alloc + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Mid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Visual)) + b += 4 + + return buf +} + +// CreateCursorCookie is a cookie used only for CreateCursor requests. +type CreateCursorCookie struct { + *xgb.Cookie +} + +// CreateCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateCursor(c *xgb.Conn, Cid Cursor, Source Pixmap, Mask Pixmap, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16, X uint16, Y uint16) CreateCursorCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(createCursorRequest(c, Cid, Source, Mask, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue, X, Y), cookie) + return CreateCursorCookie{cookie} +} + +// CreateCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateCursorCookie.Check() +func CreateCursorChecked(c *xgb.Conn, Cid Cursor, Source Pixmap, Mask Pixmap, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16, X uint16, Y uint16) CreateCursorCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(createCursorRequest(c, Cid, Source, Mask, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue, X, Y), cookie) + return CreateCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateCursor +// createCursorRequest writes a CreateCursor request to a byte slice. +func createCursorRequest(c *xgb.Conn, Cid Cursor, Source Pixmap, Mask Pixmap, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16, X uint16, Y uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + buf[b] = 93 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Source)) + b += 4 + + xgb.Put32(buf[b:], uint32(Mask)) + b += 4 + + xgb.Put16(buf[b:], ForeRed) + b += 2 + + xgb.Put16(buf[b:], ForeGreen) + b += 2 + + xgb.Put16(buf[b:], ForeBlue) + b += 2 + + xgb.Put16(buf[b:], BackRed) + b += 2 + + xgb.Put16(buf[b:], BackGreen) + b += 2 + + xgb.Put16(buf[b:], BackBlue) + b += 2 + + xgb.Put16(buf[b:], X) + b += 2 + + xgb.Put16(buf[b:], Y) + b += 2 + + return buf +} + +// CreateGCCookie is a cookie used only for CreateGC requests. +type CreateGCCookie struct { + *xgb.Cookie +} + +// CreateGC sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateGC(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) CreateGCCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(createGCRequest(c, Cid, Drawable, ValueMask, ValueList), cookie) + return CreateGCCookie{cookie} +} + +// CreateGCChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateGCCookie.Check() +func CreateGCChecked(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) CreateGCCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(createGCRequest(c, Cid, Drawable, ValueMask, ValueList), cookie) + return CreateGCCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateGCCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateGC +// createGCRequest writes a CreateGC request to a byte slice. +func createGCRequest(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((16 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + buf[b] = 55 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// CreateGlyphCursorCookie is a cookie used only for CreateGlyphCursor requests. +type CreateGlyphCursorCookie struct { + *xgb.Cookie +} + +// CreateGlyphCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateGlyphCursor(c *xgb.Conn, Cid Cursor, SourceFont Font, MaskFont Font, SourceChar uint16, MaskChar uint16, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) CreateGlyphCursorCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(createGlyphCursorRequest(c, Cid, SourceFont, MaskFont, SourceChar, MaskChar, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie) + return CreateGlyphCursorCookie{cookie} +} + +// CreateGlyphCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateGlyphCursorCookie.Check() +func CreateGlyphCursorChecked(c *xgb.Conn, Cid Cursor, SourceFont Font, MaskFont Font, SourceChar uint16, MaskChar uint16, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) CreateGlyphCursorCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(createGlyphCursorRequest(c, Cid, SourceFont, MaskFont, SourceChar, MaskChar, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie) + return CreateGlyphCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateGlyphCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateGlyphCursor +// createGlyphCursorRequest writes a CreateGlyphCursor request to a byte slice. +func createGlyphCursorRequest(c *xgb.Conn, Cid Cursor, SourceFont Font, MaskFont Font, SourceChar uint16, MaskChar uint16, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + buf[b] = 94 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cid)) + b += 4 + + xgb.Put32(buf[b:], uint32(SourceFont)) + b += 4 + + xgb.Put32(buf[b:], uint32(MaskFont)) + b += 4 + + xgb.Put16(buf[b:], SourceChar) + b += 2 + + xgb.Put16(buf[b:], MaskChar) + b += 2 + + xgb.Put16(buf[b:], ForeRed) + b += 2 + + xgb.Put16(buf[b:], ForeGreen) + b += 2 + + xgb.Put16(buf[b:], ForeBlue) + b += 2 + + xgb.Put16(buf[b:], BackRed) + b += 2 + + xgb.Put16(buf[b:], BackGreen) + b += 2 + + xgb.Put16(buf[b:], BackBlue) + b += 2 + + return buf +} + +// CreatePixmapCookie is a cookie used only for CreatePixmap requests. +type CreatePixmapCookie struct { + *xgb.Cookie +} + +// CreatePixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreatePixmap(c *xgb.Conn, Depth byte, Pid Pixmap, Drawable Drawable, Width uint16, Height uint16) CreatePixmapCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(createPixmapRequest(c, Depth, Pid, Drawable, Width, Height), cookie) + return CreatePixmapCookie{cookie} +} + +// CreatePixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using CreatePixmapCookie.Check() +func CreatePixmapChecked(c *xgb.Conn, Depth byte, Pid Pixmap, Drawable Drawable, Width uint16, Height uint16) CreatePixmapCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(createPixmapRequest(c, Depth, Pid, Drawable, Width, Height), cookie) + return CreatePixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreatePixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreatePixmap +// createPixmapRequest writes a CreatePixmap request to a byte slice. +func createPixmapRequest(c *xgb.Conn, Depth byte, Pid Pixmap, Drawable Drawable, Width uint16, Height uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 53 // request opcode + b += 1 + + buf[b] = Depth + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Pid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// CreateWindowCookie is a cookie used only for CreateWindow requests. +type CreateWindowCookie struct { + *xgb.Cookie +} + +// CreateWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateWindow(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) CreateWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(createWindowRequest(c, Depth, Wid, Parent, X, Y, Width, Height, BorderWidth, Class, Visual, ValueMask, ValueList), cookie) + return CreateWindowCookie{cookie} +} + +// CreateWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateWindowCookie.Check() +func CreateWindowChecked(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) CreateWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(createWindowRequest(c, Depth, Wid, Parent, X, Y, Width, Height, BorderWidth, Class, Visual, ValueMask, ValueList), cookie) + return CreateWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook CreateWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateWindow +// createWindowRequest writes a CreateWindow request to a byte slice. +func createWindowRequest(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) []byte { + size := xgb.Pad((32 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) + b := 0 + buf := make([]byte, size) + + buf[b] = 1 // request opcode + b += 1 + + buf[b] = Depth + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Wid)) + b += 4 + + xgb.Put32(buf[b:], uint32(Parent)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put16(buf[b:], BorderWidth) + b += 2 + + xgb.Put16(buf[b:], Class) + b += 2 + + xgb.Put32(buf[b:], uint32(Visual)) + b += 4 + + xgb.Put32(buf[b:], ValueMask) + b += 4 + + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { + xgb.Put32(buf[b:], ValueList[i]) + b += 4 + } + b = xgb.Pad(b) + + return buf +} + +// DeletePropertyCookie is a cookie used only for DeleteProperty requests. +type DeletePropertyCookie struct { + *xgb.Cookie +} + +// DeleteProperty sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteProperty(c *xgb.Conn, Window Window, Property Atom) DeletePropertyCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(deletePropertyRequest(c, Window, Property), cookie) + return DeletePropertyCookie{cookie} +} + +// DeletePropertyChecked sends a checked request. +// If an error occurs, it can be retrieved using DeletePropertyCookie.Check() +func DeletePropertyChecked(c *xgb.Conn, Window Window, Property Atom) DeletePropertyCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(deletePropertyRequest(c, Window, Property), cookie) + return DeletePropertyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeletePropertyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteProperty +// deletePropertyRequest writes a DeleteProperty request to a byte slice. +func deletePropertyRequest(c *xgb.Conn, Window Window, Property Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 19 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// DestroySubwindowsCookie is a cookie used only for DestroySubwindows requests. +type DestroySubwindowsCookie struct { + *xgb.Cookie +} + +// DestroySubwindows sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroySubwindows(c *xgb.Conn, Window Window) DestroySubwindowsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(destroySubwindowsRequest(c, Window), cookie) + return DestroySubwindowsCookie{cookie} +} + +// DestroySubwindowsChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroySubwindowsCookie.Check() +func DestroySubwindowsChecked(c *xgb.Conn, Window Window) DestroySubwindowsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(destroySubwindowsRequest(c, Window), cookie) + return DestroySubwindowsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroySubwindowsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroySubwindows +// destroySubwindowsRequest writes a DestroySubwindows request to a byte slice. +func destroySubwindowsRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 5 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// DestroyWindowCookie is a cookie used only for DestroyWindow requests. +type DestroyWindowCookie struct { + *xgb.Cookie +} + +// DestroyWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyWindow(c *xgb.Conn, Window Window) DestroyWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(destroyWindowRequest(c, Window), cookie) + return DestroyWindowCookie{cookie} +} + +// DestroyWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyWindowCookie.Check() +func DestroyWindowChecked(c *xgb.Conn, Window Window) DestroyWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(destroyWindowRequest(c, Window), cookie) + return DestroyWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyWindow +// destroyWindowRequest writes a DestroyWindow request to a byte slice. +func destroyWindowRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 4 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// FillPolyCookie is a cookie used only for FillPoly requests. +type FillPolyCookie struct { + *xgb.Cookie +} + +// FillPoly sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FillPoly(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Shape byte, CoordinateMode byte, Points []Point) FillPolyCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(fillPolyRequest(c, Drawable, Gc, Shape, CoordinateMode, Points), cookie) + return FillPolyCookie{cookie} +} + +// FillPolyChecked sends a checked request. +// If an error occurs, it can be retrieved using FillPolyCookie.Check() +func FillPolyChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Shape byte, CoordinateMode byte, Points []Point) FillPolyCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(fillPolyRequest(c, Drawable, Gc, Shape, CoordinateMode, Points), cookie) + return FillPolyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FillPolyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FillPoly +// fillPolyRequest writes a FillPoly request to a byte slice. +func fillPolyRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Shape byte, CoordinateMode byte, Points []Point) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Points) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 69 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + buf[b] = Shape + b += 1 + + buf[b] = CoordinateMode + b += 1 + + b += 2 // padding + + b += PointListBytes(buf[b:], Points) + + return buf +} + +// ForceScreenSaverCookie is a cookie used only for ForceScreenSaver requests. +type ForceScreenSaverCookie struct { + *xgb.Cookie +} + +// ForceScreenSaver sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ForceScreenSaver(c *xgb.Conn, Mode byte) ForceScreenSaverCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(forceScreenSaverRequest(c, Mode), cookie) + return ForceScreenSaverCookie{cookie} +} + +// ForceScreenSaverChecked sends a checked request. +// If an error occurs, it can be retrieved using ForceScreenSaverCookie.Check() +func ForceScreenSaverChecked(c *xgb.Conn, Mode byte) ForceScreenSaverCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(forceScreenSaverRequest(c, Mode), cookie) + return ForceScreenSaverCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ForceScreenSaverCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ForceScreenSaver +// forceScreenSaverRequest writes a ForceScreenSaver request to a byte slice. +func forceScreenSaverRequest(c *xgb.Conn, Mode byte) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 115 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// FreeColormapCookie is a cookie used only for FreeColormap requests. +type FreeColormapCookie struct { + *xgb.Cookie +} + +// FreeColormap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeColormap(c *xgb.Conn, Cmap Colormap) FreeColormapCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(freeColormapRequest(c, Cmap), cookie) + return FreeColormapCookie{cookie} +} + +// FreeColormapChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeColormapCookie.Check() +func FreeColormapChecked(c *xgb.Conn, Cmap Colormap) FreeColormapCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(freeColormapRequest(c, Cmap), cookie) + return FreeColormapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeColormapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeColormap +// freeColormapRequest writes a FreeColormap request to a byte slice. +func freeColormapRequest(c *xgb.Conn, Cmap Colormap) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 79 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + return buf +} + +// FreeColorsCookie is a cookie used only for FreeColors requests. +type FreeColorsCookie struct { + *xgb.Cookie +} + +// FreeColors sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeColors(c *xgb.Conn, Cmap Colormap, PlaneMask uint32, Pixels []uint32) FreeColorsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(freeColorsRequest(c, Cmap, PlaneMask, Pixels), cookie) + return FreeColorsCookie{cookie} +} + +// FreeColorsChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeColorsCookie.Check() +func FreeColorsChecked(c *xgb.Conn, Cmap Colormap, PlaneMask uint32, Pixels []uint32) FreeColorsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(freeColorsRequest(c, Cmap, PlaneMask, Pixels), cookie) + return FreeColorsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeColorsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeColors +// freeColorsRequest writes a FreeColors request to a byte slice. +func freeColorsRequest(c *xgb.Conn, Cmap Colormap, PlaneMask uint32, Pixels []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Pixels) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 88 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put32(buf[b:], PlaneMask) + b += 4 + + for i := 0; i < int(len(Pixels)); i++ { + xgb.Put32(buf[b:], Pixels[i]) + b += 4 + } + + return buf +} + +// FreeCursorCookie is a cookie used only for FreeCursor requests. +type FreeCursorCookie struct { + *xgb.Cookie +} + +// FreeCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeCursor(c *xgb.Conn, Cursor Cursor) FreeCursorCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(freeCursorRequest(c, Cursor), cookie) + return FreeCursorCookie{cookie} +} + +// FreeCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeCursorCookie.Check() +func FreeCursorChecked(c *xgb.Conn, Cursor Cursor) FreeCursorCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(freeCursorRequest(c, Cursor), cookie) + return FreeCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeCursor +// freeCursorRequest writes a FreeCursor request to a byte slice. +func freeCursorRequest(c *xgb.Conn, Cursor Cursor) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 95 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + return buf +} + +// FreeGCCookie is a cookie used only for FreeGC requests. +type FreeGCCookie struct { + *xgb.Cookie +} + +// FreeGC sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeGC(c *xgb.Conn, Gc Gcontext) FreeGCCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(freeGCRequest(c, Gc), cookie) + return FreeGCCookie{cookie} +} + +// FreeGCChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeGCCookie.Check() +func FreeGCChecked(c *xgb.Conn, Gc Gcontext) FreeGCCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(freeGCRequest(c, Gc), cookie) + return FreeGCCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeGCCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeGC +// freeGCRequest writes a FreeGC request to a byte slice. +func freeGCRequest(c *xgb.Conn, Gc Gcontext) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 60 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + return buf +} + +// FreePixmapCookie is a cookie used only for FreePixmap requests. +type FreePixmapCookie struct { + *xgb.Cookie +} + +// FreePixmap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreePixmap(c *xgb.Conn, Pixmap Pixmap) FreePixmapCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(freePixmapRequest(c, Pixmap), cookie) + return FreePixmapCookie{cookie} +} + +// FreePixmapChecked sends a checked request. +// If an error occurs, it can be retrieved using FreePixmapCookie.Check() +func FreePixmapChecked(c *xgb.Conn, Pixmap Pixmap) FreePixmapCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(freePixmapRequest(c, Pixmap), cookie) + return FreePixmapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreePixmapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreePixmap +// freePixmapRequest writes a FreePixmap request to a byte slice. +func freePixmapRequest(c *xgb.Conn, Pixmap Pixmap) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 54 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Pixmap)) + b += 4 + + return buf +} + +// GetAtomNameCookie is a cookie used only for GetAtomName requests. +type GetAtomNameCookie struct { + *xgb.Cookie +} + +// GetAtomName sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetAtomNameCookie.Reply() +func GetAtomName(c *xgb.Conn, Atom Atom) GetAtomNameCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getAtomNameRequest(c, Atom), cookie) + return GetAtomNameCookie{cookie} +} + +// GetAtomNameUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetAtomNameUnchecked(c *xgb.Conn, Atom Atom) GetAtomNameCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getAtomNameRequest(c, Atom), cookie) + return GetAtomNameCookie{cookie} +} + +// GetAtomNameReply represents the data returned from a GetAtomName request. +type GetAtomNameReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NameLen uint16 + // padding: 22 bytes + Name string // size: xgb.Pad((int(NameLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetAtomName request. +func (cook GetAtomNameCookie) Reply() (*GetAtomNameReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getAtomNameReply(buf), nil +} + +// getAtomNameReply reads a byte slice into a GetAtomNameReply value. +func getAtomNameReply(buf []byte) *GetAtomNameReply { + v := new(GetAtomNameReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NameLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + { + byteString := make([]byte, v.NameLen) + copy(byteString[:v.NameLen], buf[b:]) + v.Name = string(byteString) + b += int(v.NameLen) + } + + return v +} + +// Write request to wire for GetAtomName +// getAtomNameRequest writes a GetAtomName request to a byte slice. +func getAtomNameRequest(c *xgb.Conn, Atom Atom) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 17 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Atom)) + b += 4 + + return buf +} + +// GetFontPathCookie is a cookie used only for GetFontPath requests. +type GetFontPathCookie struct { + *xgb.Cookie +} + +// GetFontPath sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetFontPathCookie.Reply() +func GetFontPath(c *xgb.Conn) GetFontPathCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getFontPathRequest(c), cookie) + return GetFontPathCookie{cookie} +} + +// GetFontPathUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetFontPathUnchecked(c *xgb.Conn) GetFontPathCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getFontPathRequest(c), cookie) + return GetFontPathCookie{cookie} +} + +// GetFontPathReply represents the data returned from a GetFontPath request. +type GetFontPathReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + PathLen uint16 + // padding: 22 bytes + Path []Str // size: StrListSize(Path) +} + +// Reply blocks and returns the reply data for a GetFontPath request. +func (cook GetFontPathCookie) Reply() (*GetFontPathReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getFontPathReply(buf), nil +} + +// getFontPathReply reads a byte slice into a GetFontPathReply value. +func getFontPathReply(buf []byte) *GetFontPathReply { + v := new(GetFontPathReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PathLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Path = make([]Str, v.PathLen) + b += StrReadList(buf[b:], v.Path) + + return v +} + +// Write request to wire for GetFontPath +// getFontPathRequest writes a GetFontPath request to a byte slice. +func getFontPathRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 52 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetGeometryCookie is a cookie used only for GetGeometry requests. +type GetGeometryCookie struct { + *xgb.Cookie +} + +// GetGeometry sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetGeometryCookie.Reply() +func GetGeometry(c *xgb.Conn, Drawable Drawable) GetGeometryCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getGeometryRequest(c, Drawable), cookie) + return GetGeometryCookie{cookie} +} + +// GetGeometryUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetGeometryUnchecked(c *xgb.Conn, Drawable Drawable) GetGeometryCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getGeometryRequest(c, Drawable), cookie) + return GetGeometryCookie{cookie} +} + +// GetGeometryReply represents the data returned from a GetGeometry request. +type GetGeometryReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Depth byte + Root Window + X int16 + Y int16 + Width uint16 + Height uint16 + BorderWidth uint16 + // padding: 2 bytes +} + +// Reply blocks and returns the reply data for a GetGeometry request. +func (cook GetGeometryCookie) Reply() (*GetGeometryReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getGeometryReply(buf), nil +} + +// getGeometryReply reads a byte slice into a GetGeometryReply value. +func getGeometryReply(buf []byte) *GetGeometryReply { + v := new(GetGeometryReply) + b := 1 // skip reply determinant + + v.Depth = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.BorderWidth = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + return v +} + +// Write request to wire for GetGeometry +// getGeometryRequest writes a GetGeometry request to a byte slice. +func getGeometryRequest(c *xgb.Conn, Drawable Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 14 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// GetImageCookie is a cookie used only for GetImage requests. +type GetImageCookie struct { + *xgb.Cookie +} + +// GetImage sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetImageCookie.Reply() +func GetImage(c *xgb.Conn, Format byte, Drawable Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32) GetImageCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getImageRequest(c, Format, Drawable, X, Y, Width, Height, PlaneMask), cookie) + return GetImageCookie{cookie} +} + +// GetImageUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetImageUnchecked(c *xgb.Conn, Format byte, Drawable Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32) GetImageCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getImageRequest(c, Format, Drawable, X, Y, Width, Height, PlaneMask), cookie) + return GetImageCookie{cookie} +} + +// GetImageReply represents the data returned from a GetImage request. +type GetImageReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Depth byte + Visual Visualid + // padding: 20 bytes + Data []byte // size: xgb.Pad(((int(Length) * 4) * 1)) +} + +// Reply blocks and returns the reply data for a GetImage request. +func (cook GetImageCookie) Reply() (*GetImageReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getImageReply(buf), nil +} + +// getImageReply reads a byte slice into a GetImageReply value. +func getImageReply(buf []byte) *GetImageReply { + v := new(GetImageReply) + b := 1 // skip reply determinant + + v.Depth = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Visual = Visualid(xgb.Get32(buf[b:])) + b += 4 + + b += 20 // padding + + v.Data = make([]byte, (int(v.Length) * 4)) + copy(v.Data[:(int(v.Length)*4)], buf[b:]) + b += int((int(v.Length) * 4)) + + return v +} + +// Write request to wire for GetImage +// getImageRequest writes a GetImage request to a byte slice. +func getImageRequest(c *xgb.Conn, Format byte, Drawable Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + buf[b] = 73 // request opcode + b += 1 + + buf[b] = Format + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put32(buf[b:], PlaneMask) + b += 4 + + return buf +} + +// GetInputFocusCookie is a cookie used only for GetInputFocus requests. +type GetInputFocusCookie struct { + *xgb.Cookie +} + +// GetInputFocus sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetInputFocusCookie.Reply() +func GetInputFocus(c *xgb.Conn) GetInputFocusCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getInputFocusRequest(c), cookie) + return GetInputFocusCookie{cookie} +} + +// GetInputFocusUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetInputFocusUnchecked(c *xgb.Conn) GetInputFocusCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getInputFocusRequest(c), cookie) + return GetInputFocusCookie{cookie} +} + +// GetInputFocusReply represents the data returned from a GetInputFocus request. +type GetInputFocusReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + RevertTo byte + Focus Window +} + +// Reply blocks and returns the reply data for a GetInputFocus request. +func (cook GetInputFocusCookie) Reply() (*GetInputFocusReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getInputFocusReply(buf), nil +} + +// getInputFocusReply reads a byte slice into a GetInputFocusReply value. +func getInputFocusReply(buf []byte) *GetInputFocusReply { + v := new(GetInputFocusReply) + b := 1 // skip reply determinant + + v.RevertTo = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Focus = Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetInputFocus +// getInputFocusRequest writes a GetInputFocus request to a byte slice. +func getInputFocusRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 43 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetKeyboardControlCookie is a cookie used only for GetKeyboardControl requests. +type GetKeyboardControlCookie struct { + *xgb.Cookie +} + +// GetKeyboardControl sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetKeyboardControlCookie.Reply() +func GetKeyboardControl(c *xgb.Conn) GetKeyboardControlCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getKeyboardControlRequest(c), cookie) + return GetKeyboardControlCookie{cookie} +} + +// GetKeyboardControlUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetKeyboardControlUnchecked(c *xgb.Conn) GetKeyboardControlCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getKeyboardControlRequest(c), cookie) + return GetKeyboardControlCookie{cookie} +} + +// GetKeyboardControlReply represents the data returned from a GetKeyboardControl request. +type GetKeyboardControlReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + GlobalAutoRepeat byte + LedMask uint32 + KeyClickPercent byte + BellPercent byte + BellPitch uint16 + BellDuration uint16 + // padding: 2 bytes + AutoRepeats []byte // size: 32 +} + +// Reply blocks and returns the reply data for a GetKeyboardControl request. +func (cook GetKeyboardControlCookie) Reply() (*GetKeyboardControlReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getKeyboardControlReply(buf), nil +} + +// getKeyboardControlReply reads a byte slice into a GetKeyboardControlReply value. +func getKeyboardControlReply(buf []byte) *GetKeyboardControlReply { + v := new(GetKeyboardControlReply) + b := 1 // skip reply determinant + + v.GlobalAutoRepeat = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.LedMask = xgb.Get32(buf[b:]) + b += 4 + + v.KeyClickPercent = buf[b] + b += 1 + + v.BellPercent = buf[b] + b += 1 + + v.BellPitch = xgb.Get16(buf[b:]) + b += 2 + + v.BellDuration = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.AutoRepeats = make([]byte, 32) + copy(v.AutoRepeats[:32], buf[b:]) + b += int(32) + + return v +} + +// Write request to wire for GetKeyboardControl +// getKeyboardControlRequest writes a GetKeyboardControl request to a byte slice. +func getKeyboardControlRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 103 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetKeyboardMappingCookie is a cookie used only for GetKeyboardMapping requests. +type GetKeyboardMappingCookie struct { + *xgb.Cookie +} + +// GetKeyboardMapping sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetKeyboardMappingCookie.Reply() +func GetKeyboardMapping(c *xgb.Conn, FirstKeycode Keycode, Count byte) GetKeyboardMappingCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getKeyboardMappingRequest(c, FirstKeycode, Count), cookie) + return GetKeyboardMappingCookie{cookie} +} + +// GetKeyboardMappingUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetKeyboardMappingUnchecked(c *xgb.Conn, FirstKeycode Keycode, Count byte) GetKeyboardMappingCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getKeyboardMappingRequest(c, FirstKeycode, Count), cookie) + return GetKeyboardMappingCookie{cookie} +} + +// GetKeyboardMappingReply represents the data returned from a GetKeyboardMapping request. +type GetKeyboardMappingReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + KeysymsPerKeycode byte + // padding: 24 bytes + Keysyms []Keysym // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a GetKeyboardMapping request. +func (cook GetKeyboardMappingCookie) Reply() (*GetKeyboardMappingReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getKeyboardMappingReply(buf), nil +} + +// getKeyboardMappingReply reads a byte slice into a GetKeyboardMappingReply value. +func getKeyboardMappingReply(buf []byte) *GetKeyboardMappingReply { + v := new(GetKeyboardMappingReply) + b := 1 // skip reply determinant + + v.KeysymsPerKeycode = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Keysyms = make([]Keysym, v.Length) + for i := 0; i < int(v.Length); i++ { + v.Keysyms[i] = Keysym(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for GetKeyboardMapping +// getKeyboardMappingRequest writes a GetKeyboardMapping request to a byte slice. +func getKeyboardMappingRequest(c *xgb.Conn, FirstKeycode Keycode, Count byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 101 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = byte(FirstKeycode) + b += 1 + + buf[b] = Count + b += 1 + + return buf +} + +// GetModifierMappingCookie is a cookie used only for GetModifierMapping requests. +type GetModifierMappingCookie struct { + *xgb.Cookie +} + +// GetModifierMapping sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetModifierMappingCookie.Reply() +func GetModifierMapping(c *xgb.Conn) GetModifierMappingCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getModifierMappingRequest(c), cookie) + return GetModifierMappingCookie{cookie} +} + +// GetModifierMappingUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetModifierMappingUnchecked(c *xgb.Conn) GetModifierMappingCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getModifierMappingRequest(c), cookie) + return GetModifierMappingCookie{cookie} +} + +// GetModifierMappingReply represents the data returned from a GetModifierMapping request. +type GetModifierMappingReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + KeycodesPerModifier byte + // padding: 24 bytes + Keycodes []Keycode // size: xgb.Pad(((int(KeycodesPerModifier) * 8) * 1)) +} + +// Reply blocks and returns the reply data for a GetModifierMapping request. +func (cook GetModifierMappingCookie) Reply() (*GetModifierMappingReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getModifierMappingReply(buf), nil +} + +// getModifierMappingReply reads a byte slice into a GetModifierMappingReply value. +func getModifierMappingReply(buf []byte) *GetModifierMappingReply { + v := new(GetModifierMappingReply) + b := 1 // skip reply determinant + + v.KeycodesPerModifier = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Keycodes = make([]Keycode, (int(v.KeycodesPerModifier) * 8)) + for i := 0; i < int((int(v.KeycodesPerModifier) * 8)); i++ { + v.Keycodes[i] = Keycode(buf[b]) + b += 1 + } + + return v +} + +// Write request to wire for GetModifierMapping +// getModifierMappingRequest writes a GetModifierMapping request to a byte slice. +func getModifierMappingRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 119 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetMotionEventsCookie is a cookie used only for GetMotionEvents requests. +type GetMotionEventsCookie struct { + *xgb.Cookie +} + +// GetMotionEvents sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMotionEventsCookie.Reply() +func GetMotionEvents(c *xgb.Conn, Window Window, Start Timestamp, Stop Timestamp) GetMotionEventsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getMotionEventsRequest(c, Window, Start, Stop), cookie) + return GetMotionEventsCookie{cookie} +} + +// GetMotionEventsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMotionEventsUnchecked(c *xgb.Conn, Window Window, Start Timestamp, Stop Timestamp) GetMotionEventsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getMotionEventsRequest(c, Window, Start, Stop), cookie) + return GetMotionEventsCookie{cookie} +} + +// GetMotionEventsReply represents the data returned from a GetMotionEvents request. +type GetMotionEventsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + EventsLen uint32 + // padding: 20 bytes + Events []Timecoord // size: xgb.Pad((int(EventsLen) * 8)) +} + +// Reply blocks and returns the reply data for a GetMotionEvents request. +func (cook GetMotionEventsCookie) Reply() (*GetMotionEventsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMotionEventsReply(buf), nil +} + +// getMotionEventsReply reads a byte slice into a GetMotionEventsReply value. +func getMotionEventsReply(buf []byte) *GetMotionEventsReply { + v := new(GetMotionEventsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.EventsLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Events = make([]Timecoord, v.EventsLen) + b += TimecoordReadList(buf[b:], v.Events) + + return v +} + +// Write request to wire for GetMotionEvents +// getMotionEventsRequest writes a GetMotionEvents request to a byte slice. +func getMotionEventsRequest(c *xgb.Conn, Window Window, Start Timestamp, Stop Timestamp) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 39 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Start)) + b += 4 + + xgb.Put32(buf[b:], uint32(Stop)) + b += 4 + + return buf +} + +// GetPointerControlCookie is a cookie used only for GetPointerControl requests. +type GetPointerControlCookie struct { + *xgb.Cookie +} + +// GetPointerControl sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPointerControlCookie.Reply() +func GetPointerControl(c *xgb.Conn) GetPointerControlCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getPointerControlRequest(c), cookie) + return GetPointerControlCookie{cookie} +} + +// GetPointerControlUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPointerControlUnchecked(c *xgb.Conn) GetPointerControlCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getPointerControlRequest(c), cookie) + return GetPointerControlCookie{cookie} +} + +// GetPointerControlReply represents the data returned from a GetPointerControl request. +type GetPointerControlReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + AccelerationNumerator uint16 + AccelerationDenominator uint16 + Threshold uint16 + // padding: 18 bytes +} + +// Reply blocks and returns the reply data for a GetPointerControl request. +func (cook GetPointerControlCookie) Reply() (*GetPointerControlReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPointerControlReply(buf), nil +} + +// getPointerControlReply reads a byte slice into a GetPointerControlReply value. +func getPointerControlReply(buf []byte) *GetPointerControlReply { + v := new(GetPointerControlReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.AccelerationNumerator = xgb.Get16(buf[b:]) + b += 2 + + v.AccelerationDenominator = xgb.Get16(buf[b:]) + b += 2 + + v.Threshold = xgb.Get16(buf[b:]) + b += 2 + + b += 18 // padding + + return v +} + +// Write request to wire for GetPointerControl +// getPointerControlRequest writes a GetPointerControl request to a byte slice. +func getPointerControlRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 106 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetPointerMappingCookie is a cookie used only for GetPointerMapping requests. +type GetPointerMappingCookie struct { + *xgb.Cookie +} + +// GetPointerMapping sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPointerMappingCookie.Reply() +func GetPointerMapping(c *xgb.Conn) GetPointerMappingCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getPointerMappingRequest(c), cookie) + return GetPointerMappingCookie{cookie} +} + +// GetPointerMappingUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPointerMappingUnchecked(c *xgb.Conn) GetPointerMappingCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getPointerMappingRequest(c), cookie) + return GetPointerMappingCookie{cookie} +} + +// GetPointerMappingReply represents the data returned from a GetPointerMapping request. +type GetPointerMappingReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + MapLen byte + // padding: 24 bytes + Map []byte // size: xgb.Pad((int(MapLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetPointerMapping request. +func (cook GetPointerMappingCookie) Reply() (*GetPointerMappingReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPointerMappingReply(buf), nil +} + +// getPointerMappingReply reads a byte slice into a GetPointerMappingReply value. +func getPointerMappingReply(buf []byte) *GetPointerMappingReply { + v := new(GetPointerMappingReply) + b := 1 // skip reply determinant + + v.MapLen = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Map = make([]byte, v.MapLen) + copy(v.Map[:v.MapLen], buf[b:]) + b += int(v.MapLen) + + return v +} + +// Write request to wire for GetPointerMapping +// getPointerMappingRequest writes a GetPointerMapping request to a byte slice. +func getPointerMappingRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 117 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetPropertyCookie is a cookie used only for GetProperty requests. +type GetPropertyCookie struct { + *xgb.Cookie +} + +// GetProperty sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPropertyCookie.Reply() +func GetProperty(c *xgb.Conn, Delete bool, Window Window, Property Atom, Type Atom, LongOffset uint32, LongLength uint32) GetPropertyCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getPropertyRequest(c, Delete, Window, Property, Type, LongOffset, LongLength), cookie) + return GetPropertyCookie{cookie} +} + +// GetPropertyUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPropertyUnchecked(c *xgb.Conn, Delete bool, Window Window, Property Atom, Type Atom, LongOffset uint32, LongLength uint32) GetPropertyCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getPropertyRequest(c, Delete, Window, Property, Type, LongOffset, LongLength), cookie) + return GetPropertyCookie{cookie} +} + +// GetPropertyReply represents the data returned from a GetProperty request. +type GetPropertyReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Format byte + Type Atom + BytesAfter uint32 + ValueLen uint32 + // padding: 12 bytes + Value []byte // size: xgb.Pad(((int(ValueLen) * (int(Format) / 8)) * 1)) +} + +// Reply blocks and returns the reply data for a GetProperty request. +func (cook GetPropertyCookie) Reply() (*GetPropertyReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPropertyReply(buf), nil +} + +// getPropertyReply reads a byte slice into a GetPropertyReply value. +func getPropertyReply(buf []byte) *GetPropertyReply { + v := new(GetPropertyReply) + b := 1 // skip reply determinant + + v.Format = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Type = Atom(xgb.Get32(buf[b:])) + b += 4 + + v.BytesAfter = xgb.Get32(buf[b:]) + b += 4 + + v.ValueLen = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Value = make([]byte, (int(v.ValueLen) * (int(v.Format) / 8))) + copy(v.Value[:(int(v.ValueLen)*(int(v.Format)/8))], buf[b:]) + b += int((int(v.ValueLen) * (int(v.Format) / 8))) + + return v +} + +// Write request to wire for GetProperty +// getPropertyRequest writes a GetProperty request to a byte slice. +func getPropertyRequest(c *xgb.Conn, Delete bool, Window Window, Property Atom, Type Atom, LongOffset uint32, LongLength uint32) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + buf[b] = 20 // request opcode + b += 1 + + if Delete { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + xgb.Put32(buf[b:], uint32(Type)) + b += 4 + + xgb.Put32(buf[b:], LongOffset) + b += 4 + + xgb.Put32(buf[b:], LongLength) + b += 4 + + return buf +} + +// GetScreenSaverCookie is a cookie used only for GetScreenSaver requests. +type GetScreenSaverCookie struct { + *xgb.Cookie +} + +// GetScreenSaver sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetScreenSaverCookie.Reply() +func GetScreenSaver(c *xgb.Conn) GetScreenSaverCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getScreenSaverRequest(c), cookie) + return GetScreenSaverCookie{cookie} +} + +// GetScreenSaverUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetScreenSaverUnchecked(c *xgb.Conn) GetScreenSaverCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getScreenSaverRequest(c), cookie) + return GetScreenSaverCookie{cookie} +} + +// GetScreenSaverReply represents the data returned from a GetScreenSaver request. +type GetScreenSaverReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Timeout uint16 + Interval uint16 + PreferBlanking byte + AllowExposures byte + // padding: 18 bytes +} + +// Reply blocks and returns the reply data for a GetScreenSaver request. +func (cook GetScreenSaverCookie) Reply() (*GetScreenSaverReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getScreenSaverReply(buf), nil +} + +// getScreenSaverReply reads a byte slice into a GetScreenSaverReply value. +func getScreenSaverReply(buf []byte) *GetScreenSaverReply { + v := new(GetScreenSaverReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timeout = xgb.Get16(buf[b:]) + b += 2 + + v.Interval = xgb.Get16(buf[b:]) + b += 2 + + v.PreferBlanking = buf[b] + b += 1 + + v.AllowExposures = buf[b] + b += 1 + + b += 18 // padding + + return v +} + +// Write request to wire for GetScreenSaver +// getScreenSaverRequest writes a GetScreenSaver request to a byte slice. +func getScreenSaverRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 108 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetSelectionOwnerCookie is a cookie used only for GetSelectionOwner requests. +type GetSelectionOwnerCookie struct { + *xgb.Cookie +} + +// GetSelectionOwner sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetSelectionOwnerCookie.Reply() +func GetSelectionOwner(c *xgb.Conn, Selection Atom) GetSelectionOwnerCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getSelectionOwnerRequest(c, Selection), cookie) + return GetSelectionOwnerCookie{cookie} +} + +// GetSelectionOwnerUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetSelectionOwnerUnchecked(c *xgb.Conn, Selection Atom) GetSelectionOwnerCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getSelectionOwnerRequest(c, Selection), cookie) + return GetSelectionOwnerCookie{cookie} +} + +// GetSelectionOwnerReply represents the data returned from a GetSelectionOwner request. +type GetSelectionOwnerReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Owner Window +} + +// Reply blocks and returns the reply data for a GetSelectionOwner request. +func (cook GetSelectionOwnerCookie) Reply() (*GetSelectionOwnerReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getSelectionOwnerReply(buf), nil +} + +// getSelectionOwnerReply reads a byte slice into a GetSelectionOwnerReply value. +func getSelectionOwnerReply(buf []byte) *GetSelectionOwnerReply { + v := new(GetSelectionOwnerReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Owner = Window(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetSelectionOwner +// getSelectionOwnerRequest writes a GetSelectionOwner request to a byte slice. +func getSelectionOwnerRequest(c *xgb.Conn, Selection Atom) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 23 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Selection)) + b += 4 + + return buf +} + +// GetWindowAttributesCookie is a cookie used only for GetWindowAttributes requests. +type GetWindowAttributesCookie struct { + *xgb.Cookie +} + +// GetWindowAttributes sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetWindowAttributesCookie.Reply() +func GetWindowAttributes(c *xgb.Conn, Window Window) GetWindowAttributesCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(getWindowAttributesRequest(c, Window), cookie) + return GetWindowAttributesCookie{cookie} +} + +// GetWindowAttributesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetWindowAttributesUnchecked(c *xgb.Conn, Window Window) GetWindowAttributesCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(getWindowAttributesRequest(c, Window), cookie) + return GetWindowAttributesCookie{cookie} +} + +// GetWindowAttributesReply represents the data returned from a GetWindowAttributes request. +type GetWindowAttributesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + BackingStore byte + Visual Visualid + Class uint16 + BitGravity byte + WinGravity byte + BackingPlanes uint32 + BackingPixel uint32 + SaveUnder bool + MapIsInstalled bool + MapState byte + OverrideRedirect bool + Colormap Colormap + AllEventMasks uint32 + YourEventMask uint32 + DoNotPropagateMask uint16 + // padding: 2 bytes +} + +// Reply blocks and returns the reply data for a GetWindowAttributes request. +func (cook GetWindowAttributesCookie) Reply() (*GetWindowAttributesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getWindowAttributesReply(buf), nil +} + +// getWindowAttributesReply reads a byte slice into a GetWindowAttributesReply value. +func getWindowAttributesReply(buf []byte) *GetWindowAttributesReply { + v := new(GetWindowAttributesReply) + b := 1 // skip reply determinant + + v.BackingStore = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Visual = Visualid(xgb.Get32(buf[b:])) + b += 4 + + v.Class = xgb.Get16(buf[b:]) + b += 2 + + v.BitGravity = buf[b] + b += 1 + + v.WinGravity = buf[b] + b += 1 + + v.BackingPlanes = xgb.Get32(buf[b:]) + b += 4 + + v.BackingPixel = xgb.Get32(buf[b:]) + b += 4 + + if buf[b] == 1 { + v.SaveUnder = true + } else { + v.SaveUnder = false + } + b += 1 + + if buf[b] == 1 { + v.MapIsInstalled = true + } else { + v.MapIsInstalled = false + } + b += 1 + + v.MapState = buf[b] + b += 1 + + if buf[b] == 1 { + v.OverrideRedirect = true + } else { + v.OverrideRedirect = false + } + b += 1 + + v.Colormap = Colormap(xgb.Get32(buf[b:])) + b += 4 + + v.AllEventMasks = xgb.Get32(buf[b:]) + b += 4 + + v.YourEventMask = xgb.Get32(buf[b:]) + b += 4 + + v.DoNotPropagateMask = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + return v +} + +// Write request to wire for GetWindowAttributes +// getWindowAttributesRequest writes a GetWindowAttributes request to a byte slice. +func getWindowAttributesRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 3 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GrabButtonCookie is a cookie used only for GrabButton requests. +type GrabButtonCookie struct { + *xgb.Cookie +} + +// GrabButton sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabButton(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Button byte, Modifiers uint16) GrabButtonCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(grabButtonRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Button, Modifiers), cookie) + return GrabButtonCookie{cookie} +} + +// GrabButtonChecked sends a checked request. +// If an error occurs, it can be retrieved using GrabButtonCookie.Check() +func GrabButtonChecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Button byte, Modifiers uint16) GrabButtonCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(grabButtonRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Button, Modifiers), cookie) + return GrabButtonCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook GrabButtonCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for GrabButton +// grabButtonRequest writes a GrabButton request to a byte slice. +func grabButtonRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Button byte, Modifiers uint16) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + buf[b] = 28 // request opcode + b += 1 + + if OwnerEvents { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GrabWindow)) + b += 4 + + xgb.Put16(buf[b:], EventMask) + b += 2 + + buf[b] = PointerMode + b += 1 + + buf[b] = KeyboardMode + b += 1 + + xgb.Put32(buf[b:], uint32(ConfineTo)) + b += 4 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + buf[b] = Button + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], Modifiers) + b += 2 + + return buf +} + +// GrabKeyCookie is a cookie used only for GrabKey requests. +type GrabKeyCookie struct { + *xgb.Cookie +} + +// GrabKey sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabKey(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Modifiers uint16, Key Keycode, PointerMode byte, KeyboardMode byte) GrabKeyCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(grabKeyRequest(c, OwnerEvents, GrabWindow, Modifiers, Key, PointerMode, KeyboardMode), cookie) + return GrabKeyCookie{cookie} +} + +// GrabKeyChecked sends a checked request. +// If an error occurs, it can be retrieved using GrabKeyCookie.Check() +func GrabKeyChecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Modifiers uint16, Key Keycode, PointerMode byte, KeyboardMode byte) GrabKeyCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(grabKeyRequest(c, OwnerEvents, GrabWindow, Modifiers, Key, PointerMode, KeyboardMode), cookie) + return GrabKeyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook GrabKeyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for GrabKey +// grabKeyRequest writes a GrabKey request to a byte slice. +func grabKeyRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Modifiers uint16, Key Keycode, PointerMode byte, KeyboardMode byte) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 33 // request opcode + b += 1 + + if OwnerEvents { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GrabWindow)) + b += 4 + + xgb.Put16(buf[b:], Modifiers) + b += 2 + + buf[b] = byte(Key) + b += 1 + + buf[b] = PointerMode + b += 1 + + buf[b] = KeyboardMode + b += 1 + + b += 3 // padding + + return buf +} + +// GrabKeyboardCookie is a cookie used only for GrabKeyboard requests. +type GrabKeyboardCookie struct { + *xgb.Cookie +} + +// GrabKeyboard sends a checked request. +// If an error occurs, it will be returned with the reply by calling GrabKeyboardCookie.Reply() +func GrabKeyboard(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Time Timestamp, PointerMode byte, KeyboardMode byte) GrabKeyboardCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(grabKeyboardRequest(c, OwnerEvents, GrabWindow, Time, PointerMode, KeyboardMode), cookie) + return GrabKeyboardCookie{cookie} +} + +// GrabKeyboardUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabKeyboardUnchecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Time Timestamp, PointerMode byte, KeyboardMode byte) GrabKeyboardCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(grabKeyboardRequest(c, OwnerEvents, GrabWindow, Time, PointerMode, KeyboardMode), cookie) + return GrabKeyboardCookie{cookie} +} + +// GrabKeyboardReply represents the data returned from a GrabKeyboard request. +type GrabKeyboardReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte +} + +// Reply blocks and returns the reply data for a GrabKeyboard request. +func (cook GrabKeyboardCookie) Reply() (*GrabKeyboardReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return grabKeyboardReply(buf), nil +} + +// grabKeyboardReply reads a byte slice into a GrabKeyboardReply value. +func grabKeyboardReply(buf []byte) *GrabKeyboardReply { + v := new(GrabKeyboardReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for GrabKeyboard +// grabKeyboardRequest writes a GrabKeyboard request to a byte slice. +func grabKeyboardRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Time Timestamp, PointerMode byte, KeyboardMode byte) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 31 // request opcode + b += 1 + + if OwnerEvents { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GrabWindow)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + buf[b] = PointerMode + b += 1 + + buf[b] = KeyboardMode + b += 1 + + b += 2 // padding + + return buf +} + +// GrabPointerCookie is a cookie used only for GrabPointer requests. +type GrabPointerCookie struct { + *xgb.Cookie +} + +// GrabPointer sends a checked request. +// If an error occurs, it will be returned with the reply by calling GrabPointerCookie.Reply() +func GrabPointer(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Time Timestamp) GrabPointerCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(grabPointerRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Time), cookie) + return GrabPointerCookie{cookie} +} + +// GrabPointerUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabPointerUnchecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Time Timestamp) GrabPointerCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(grabPointerRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Time), cookie) + return GrabPointerCookie{cookie} +} + +// GrabPointerReply represents the data returned from a GrabPointer request. +type GrabPointerReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte +} + +// Reply blocks and returns the reply data for a GrabPointer request. +func (cook GrabPointerCookie) Reply() (*GrabPointerReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return grabPointerReply(buf), nil +} + +// grabPointerReply reads a byte slice into a GrabPointerReply value. +func grabPointerReply(buf []byte) *GrabPointerReply { + v := new(GrabPointerReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for GrabPointer +// grabPointerRequest writes a GrabPointer request to a byte slice. +func grabPointerRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Time Timestamp) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + buf[b] = 26 // request opcode + b += 1 + + if OwnerEvents { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GrabWindow)) + b += 4 + + xgb.Put16(buf[b:], EventMask) + b += 2 + + buf[b] = PointerMode + b += 1 + + buf[b] = KeyboardMode + b += 1 + + xgb.Put32(buf[b:], uint32(ConfineTo)) + b += 4 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// GrabServerCookie is a cookie used only for GrabServer requests. +type GrabServerCookie struct { + *xgb.Cookie +} + +// GrabServer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabServer(c *xgb.Conn) GrabServerCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(grabServerRequest(c), cookie) + return GrabServerCookie{cookie} +} + +// GrabServerChecked sends a checked request. +// If an error occurs, it can be retrieved using GrabServerCookie.Check() +func GrabServerChecked(c *xgb.Conn) GrabServerCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(grabServerRequest(c), cookie) + return GrabServerCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook GrabServerCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for GrabServer +// grabServerRequest writes a GrabServer request to a byte slice. +func grabServerRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 36 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// ImageText16Cookie is a cookie used only for ImageText16 requests. +type ImageText16Cookie struct { + *xgb.Cookie +} + +// ImageText16 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ImageText16(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String []Char2b) ImageText16Cookie { + cookie := c.NewCookie(false, false) + c.NewRequest(imageText16Request(c, StringLen, Drawable, Gc, X, Y, String), cookie) + return ImageText16Cookie{cookie} +} + +// ImageText16Checked sends a checked request. +// If an error occurs, it can be retrieved using ImageText16Cookie.Check() +func ImageText16Checked(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String []Char2b) ImageText16Cookie { + cookie := c.NewCookie(true, false) + c.NewRequest(imageText16Request(c, StringLen, Drawable, Gc, X, Y, String), cookie) + return ImageText16Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ImageText16Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ImageText16 +// imageText16Request writes a ImageText16 request to a byte slice. +func imageText16Request(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String []Char2b) []byte { + size := xgb.Pad((16 + xgb.Pad((int(StringLen) * 2)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 77 // request opcode + b += 1 + + buf[b] = StringLen + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + b += Char2bListBytes(buf[b:], String) + + return buf +} + +// ImageText8Cookie is a cookie used only for ImageText8 requests. +type ImageText8Cookie struct { + *xgb.Cookie +} + +// ImageText8 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ImageText8(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String string) ImageText8Cookie { + cookie := c.NewCookie(false, false) + c.NewRequest(imageText8Request(c, StringLen, Drawable, Gc, X, Y, String), cookie) + return ImageText8Cookie{cookie} +} + +// ImageText8Checked sends a checked request. +// If an error occurs, it can be retrieved using ImageText8Cookie.Check() +func ImageText8Checked(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String string) ImageText8Cookie { + cookie := c.NewCookie(true, false) + c.NewRequest(imageText8Request(c, StringLen, Drawable, Gc, X, Y, String), cookie) + return ImageText8Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ImageText8Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ImageText8 +// imageText8Request writes a ImageText8 request to a byte slice. +func imageText8Request(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String string) []byte { + size := xgb.Pad((16 + xgb.Pad((int(StringLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 76 // request opcode + b += 1 + + buf[b] = StringLen + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + copy(buf[b:], String[:StringLen]) + b += int(StringLen) + + return buf +} + +// InstallColormapCookie is a cookie used only for InstallColormap requests. +type InstallColormapCookie struct { + *xgb.Cookie +} + +// InstallColormap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func InstallColormap(c *xgb.Conn, Cmap Colormap) InstallColormapCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(installColormapRequest(c, Cmap), cookie) + return InstallColormapCookie{cookie} +} + +// InstallColormapChecked sends a checked request. +// If an error occurs, it can be retrieved using InstallColormapCookie.Check() +func InstallColormapChecked(c *xgb.Conn, Cmap Colormap) InstallColormapCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(installColormapRequest(c, Cmap), cookie) + return InstallColormapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook InstallColormapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for InstallColormap +// installColormapRequest writes a InstallColormap request to a byte slice. +func installColormapRequest(c *xgb.Conn, Cmap Colormap) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 81 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + return buf +} + +// InternAtomCookie is a cookie used only for InternAtom requests. +type InternAtomCookie struct { + *xgb.Cookie +} + +// InternAtom sends a checked request. +// If an error occurs, it will be returned with the reply by calling InternAtomCookie.Reply() +func InternAtom(c *xgb.Conn, OnlyIfExists bool, NameLen uint16, Name string) InternAtomCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(internAtomRequest(c, OnlyIfExists, NameLen, Name), cookie) + return InternAtomCookie{cookie} +} + +// InternAtomUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func InternAtomUnchecked(c *xgb.Conn, OnlyIfExists bool, NameLen uint16, Name string) InternAtomCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(internAtomRequest(c, OnlyIfExists, NameLen, Name), cookie) + return InternAtomCookie{cookie} +} + +// InternAtomReply represents the data returned from a InternAtom request. +type InternAtomReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Atom Atom +} + +// Reply blocks and returns the reply data for a InternAtom request. +func (cook InternAtomCookie) Reply() (*InternAtomReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return internAtomReply(buf), nil +} + +// internAtomReply reads a byte slice into a InternAtomReply value. +func internAtomReply(buf []byte) *InternAtomReply { + v := new(InternAtomReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Atom = Atom(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for InternAtom +// internAtomRequest writes a InternAtom request to a byte slice. +func internAtomRequest(c *xgb.Conn, OnlyIfExists bool, NameLen uint16, Name string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 16 // request opcode + b += 1 + + if OnlyIfExists { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], NameLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:NameLen]) + b += int(NameLen) + + return buf +} + +// KillClientCookie is a cookie used only for KillClient requests. +type KillClientCookie struct { + *xgb.Cookie +} + +// KillClient sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func KillClient(c *xgb.Conn, Resource uint32) KillClientCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(killClientRequest(c, Resource), cookie) + return KillClientCookie{cookie} +} + +// KillClientChecked sends a checked request. +// If an error occurs, it can be retrieved using KillClientCookie.Check() +func KillClientChecked(c *xgb.Conn, Resource uint32) KillClientCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(killClientRequest(c, Resource), cookie) + return KillClientCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook KillClientCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for KillClient +// killClientRequest writes a KillClient request to a byte slice. +func killClientRequest(c *xgb.Conn, Resource uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 113 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Resource) + b += 4 + + return buf +} + +// ListExtensionsCookie is a cookie used only for ListExtensions requests. +type ListExtensionsCookie struct { + *xgb.Cookie +} + +// ListExtensions sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListExtensionsCookie.Reply() +func ListExtensions(c *xgb.Conn) ListExtensionsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(listExtensionsRequest(c), cookie) + return ListExtensionsCookie{cookie} +} + +// ListExtensionsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListExtensionsUnchecked(c *xgb.Conn) ListExtensionsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(listExtensionsRequest(c), cookie) + return ListExtensionsCookie{cookie} +} + +// ListExtensionsReply represents the data returned from a ListExtensions request. +type ListExtensionsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + NamesLen byte + // padding: 24 bytes + Names []Str // size: StrListSize(Names) +} + +// Reply blocks and returns the reply data for a ListExtensions request. +func (cook ListExtensionsCookie) Reply() (*ListExtensionsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listExtensionsReply(buf), nil +} + +// listExtensionsReply reads a byte slice into a ListExtensionsReply value. +func listExtensionsReply(buf []byte) *ListExtensionsReply { + v := new(ListExtensionsReply) + b := 1 // skip reply determinant + + v.NamesLen = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.Names = make([]Str, v.NamesLen) + b += StrReadList(buf[b:], v.Names) + + return v +} + +// Write request to wire for ListExtensions +// listExtensionsRequest writes a ListExtensions request to a byte slice. +func listExtensionsRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 99 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// ListFontsCookie is a cookie used only for ListFonts requests. +type ListFontsCookie struct { + *xgb.Cookie +} + +// ListFonts sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListFontsCookie.Reply() +func ListFonts(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(listFontsRequest(c, MaxNames, PatternLen, Pattern), cookie) + return ListFontsCookie{cookie} +} + +// ListFontsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListFontsUnchecked(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(listFontsRequest(c, MaxNames, PatternLen, Pattern), cookie) + return ListFontsCookie{cookie} +} + +// ListFontsReply represents the data returned from a ListFonts request. +type ListFontsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NamesLen uint16 + // padding: 22 bytes + Names []Str // size: StrListSize(Names) +} + +// Reply blocks and returns the reply data for a ListFonts request. +func (cook ListFontsCookie) Reply() (*ListFontsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listFontsReply(buf), nil +} + +// listFontsReply reads a byte slice into a ListFontsReply value. +func listFontsReply(buf []byte) *ListFontsReply { + v := new(ListFontsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NamesLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Names = make([]Str, v.NamesLen) + b += StrReadList(buf[b:], v.Names) + + return v +} + +// Write request to wire for ListFonts +// listFontsRequest writes a ListFonts request to a byte slice. +func listFontsRequest(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(PatternLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 49 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], MaxNames) + b += 2 + + xgb.Put16(buf[b:], PatternLen) + b += 2 + + copy(buf[b:], Pattern[:PatternLen]) + b += int(PatternLen) + + return buf +} + +// ListFontsWithInfoCookie is a cookie used only for ListFontsWithInfo requests. +type ListFontsWithInfoCookie struct { + *xgb.Cookie +} + +// ListFontsWithInfo sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListFontsWithInfoCookie.Reply() +func ListFontsWithInfo(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsWithInfoCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(listFontsWithInfoRequest(c, MaxNames, PatternLen, Pattern), cookie) + return ListFontsWithInfoCookie{cookie} +} + +// ListFontsWithInfoUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListFontsWithInfoUnchecked(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsWithInfoCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(listFontsWithInfoRequest(c, MaxNames, PatternLen, Pattern), cookie) + return ListFontsWithInfoCookie{cookie} +} + +// ListFontsWithInfoReply represents the data returned from a ListFontsWithInfo request. +type ListFontsWithInfoReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + NameLen byte + MinBounds Charinfo + // padding: 4 bytes + MaxBounds Charinfo + // padding: 4 bytes + MinCharOrByte2 uint16 + MaxCharOrByte2 uint16 + DefaultChar uint16 + PropertiesLen uint16 + DrawDirection byte + MinByte1 byte + MaxByte1 byte + AllCharsExist bool + FontAscent int16 + FontDescent int16 + RepliesHint uint32 + Properties []Fontprop // size: xgb.Pad((int(PropertiesLen) * 8)) + Name string // size: xgb.Pad((int(NameLen) * 1)) +} + +// Reply blocks and returns the reply data for a ListFontsWithInfo request. +func (cook ListFontsWithInfoCookie) Reply() (*ListFontsWithInfoReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listFontsWithInfoReply(buf), nil +} + +// listFontsWithInfoReply reads a byte slice into a ListFontsWithInfoReply value. +func listFontsWithInfoReply(buf []byte) *ListFontsWithInfoReply { + v := new(ListFontsWithInfoReply) + b := 1 // skip reply determinant + + v.NameLen = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MinBounds = Charinfo{} + b += CharinfoRead(buf[b:], &v.MinBounds) + + b += 4 // padding + + v.MaxBounds = Charinfo{} + b += CharinfoRead(buf[b:], &v.MaxBounds) + + b += 4 // padding + + v.MinCharOrByte2 = xgb.Get16(buf[b:]) + b += 2 + + v.MaxCharOrByte2 = xgb.Get16(buf[b:]) + b += 2 + + v.DefaultChar = xgb.Get16(buf[b:]) + b += 2 + + v.PropertiesLen = xgb.Get16(buf[b:]) + b += 2 + + v.DrawDirection = buf[b] + b += 1 + + v.MinByte1 = buf[b] + b += 1 + + v.MaxByte1 = buf[b] + b += 1 + + if buf[b] == 1 { + v.AllCharsExist = true + } else { + v.AllCharsExist = false + } + b += 1 + + v.FontAscent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.FontDescent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RepliesHint = xgb.Get32(buf[b:]) + b += 4 + + v.Properties = make([]Fontprop, v.PropertiesLen) + b += FontpropReadList(buf[b:], v.Properties) + + { + byteString := make([]byte, v.NameLen) + copy(byteString[:v.NameLen], buf[b:]) + v.Name = string(byteString) + b += int(v.NameLen) + } + + return v +} + +// Write request to wire for ListFontsWithInfo +// listFontsWithInfoRequest writes a ListFontsWithInfo request to a byte slice. +func listFontsWithInfoRequest(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(PatternLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 50 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], MaxNames) + b += 2 + + xgb.Put16(buf[b:], PatternLen) + b += 2 + + copy(buf[b:], Pattern[:PatternLen]) + b += int(PatternLen) + + return buf +} + +// ListHostsCookie is a cookie used only for ListHosts requests. +type ListHostsCookie struct { + *xgb.Cookie +} + +// ListHosts sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListHostsCookie.Reply() +func ListHosts(c *xgb.Conn) ListHostsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(listHostsRequest(c), cookie) + return ListHostsCookie{cookie} +} + +// ListHostsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListHostsUnchecked(c *xgb.Conn) ListHostsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(listHostsRequest(c), cookie) + return ListHostsCookie{cookie} +} + +// ListHostsReply represents the data returned from a ListHosts request. +type ListHostsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Mode byte + HostsLen uint16 + // padding: 22 bytes + Hosts []Host // size: HostListSize(Hosts) +} + +// Reply blocks and returns the reply data for a ListHosts request. +func (cook ListHostsCookie) Reply() (*ListHostsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listHostsReply(buf), nil +} + +// listHostsReply reads a byte slice into a ListHostsReply value. +func listHostsReply(buf []byte) *ListHostsReply { + v := new(ListHostsReply) + b := 1 // skip reply determinant + + v.Mode = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.HostsLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Hosts = make([]Host, v.HostsLen) + b += HostReadList(buf[b:], v.Hosts) + + return v +} + +// Write request to wire for ListHosts +// listHostsRequest writes a ListHosts request to a byte slice. +func listHostsRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 110 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// ListInstalledColormapsCookie is a cookie used only for ListInstalledColormaps requests. +type ListInstalledColormapsCookie struct { + *xgb.Cookie +} + +// ListInstalledColormaps sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListInstalledColormapsCookie.Reply() +func ListInstalledColormaps(c *xgb.Conn, Window Window) ListInstalledColormapsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(listInstalledColormapsRequest(c, Window), cookie) + return ListInstalledColormapsCookie{cookie} +} + +// ListInstalledColormapsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListInstalledColormapsUnchecked(c *xgb.Conn, Window Window) ListInstalledColormapsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(listInstalledColormapsRequest(c, Window), cookie) + return ListInstalledColormapsCookie{cookie} +} + +// ListInstalledColormapsReply represents the data returned from a ListInstalledColormaps request. +type ListInstalledColormapsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + CmapsLen uint16 + // padding: 22 bytes + Cmaps []Colormap // size: xgb.Pad((int(CmapsLen) * 4)) +} + +// Reply blocks and returns the reply data for a ListInstalledColormaps request. +func (cook ListInstalledColormapsCookie) Reply() (*ListInstalledColormapsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listInstalledColormapsReply(buf), nil +} + +// listInstalledColormapsReply reads a byte slice into a ListInstalledColormapsReply value. +func listInstalledColormapsReply(buf []byte) *ListInstalledColormapsReply { + v := new(ListInstalledColormapsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.CmapsLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Cmaps = make([]Colormap, v.CmapsLen) + for i := 0; i < int(v.CmapsLen); i++ { + v.Cmaps[i] = Colormap(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for ListInstalledColormaps +// listInstalledColormapsRequest writes a ListInstalledColormaps request to a byte slice. +func listInstalledColormapsRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 83 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// ListPropertiesCookie is a cookie used only for ListProperties requests. +type ListPropertiesCookie struct { + *xgb.Cookie +} + +// ListProperties sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListPropertiesCookie.Reply() +func ListProperties(c *xgb.Conn, Window Window) ListPropertiesCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(listPropertiesRequest(c, Window), cookie) + return ListPropertiesCookie{cookie} +} + +// ListPropertiesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListPropertiesUnchecked(c *xgb.Conn, Window Window) ListPropertiesCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(listPropertiesRequest(c, Window), cookie) + return ListPropertiesCookie{cookie} +} + +// ListPropertiesReply represents the data returned from a ListProperties request. +type ListPropertiesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + AtomsLen uint16 + // padding: 22 bytes + Atoms []Atom // size: xgb.Pad((int(AtomsLen) * 4)) +} + +// Reply blocks and returns the reply data for a ListProperties request. +func (cook ListPropertiesCookie) Reply() (*ListPropertiesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listPropertiesReply(buf), nil +} + +// listPropertiesReply reads a byte slice into a ListPropertiesReply value. +func listPropertiesReply(buf []byte) *ListPropertiesReply { + v := new(ListPropertiesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.AtomsLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Atoms = make([]Atom, v.AtomsLen) + for i := 0; i < int(v.AtomsLen); i++ { + v.Atoms[i] = Atom(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for ListProperties +// listPropertiesRequest writes a ListProperties request to a byte slice. +func listPropertiesRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 21 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// LookupColorCookie is a cookie used only for LookupColor requests. +type LookupColorCookie struct { + *xgb.Cookie +} + +// LookupColor sends a checked request. +// If an error occurs, it will be returned with the reply by calling LookupColorCookie.Reply() +func LookupColor(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) LookupColorCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(lookupColorRequest(c, Cmap, NameLen, Name), cookie) + return LookupColorCookie{cookie} +} + +// LookupColorUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func LookupColorUnchecked(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) LookupColorCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(lookupColorRequest(c, Cmap, NameLen, Name), cookie) + return LookupColorCookie{cookie} +} + +// LookupColorReply represents the data returned from a LookupColor request. +type LookupColorReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ExactRed uint16 + ExactGreen uint16 + ExactBlue uint16 + VisualRed uint16 + VisualGreen uint16 + VisualBlue uint16 +} + +// Reply blocks and returns the reply data for a LookupColor request. +func (cook LookupColorCookie) Reply() (*LookupColorReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return lookupColorReply(buf), nil +} + +// lookupColorReply reads a byte slice into a LookupColorReply value. +func lookupColorReply(buf []byte) *LookupColorReply { + v := new(LookupColorReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ExactRed = xgb.Get16(buf[b:]) + b += 2 + + v.ExactGreen = xgb.Get16(buf[b:]) + b += 2 + + v.ExactBlue = xgb.Get16(buf[b:]) + b += 2 + + v.VisualRed = xgb.Get16(buf[b:]) + b += 2 + + v.VisualGreen = xgb.Get16(buf[b:]) + b += 2 + + v.VisualBlue = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for LookupColor +// lookupColorRequest writes a LookupColor request to a byte slice. +func lookupColorRequest(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) []byte { + size := xgb.Pad((12 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 92 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put16(buf[b:], NameLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:NameLen]) + b += int(NameLen) + + return buf +} + +// MapSubwindowsCookie is a cookie used only for MapSubwindows requests. +type MapSubwindowsCookie struct { + *xgb.Cookie +} + +// MapSubwindows sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func MapSubwindows(c *xgb.Conn, Window Window) MapSubwindowsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(mapSubwindowsRequest(c, Window), cookie) + return MapSubwindowsCookie{cookie} +} + +// MapSubwindowsChecked sends a checked request. +// If an error occurs, it can be retrieved using MapSubwindowsCookie.Check() +func MapSubwindowsChecked(c *xgb.Conn, Window Window) MapSubwindowsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(mapSubwindowsRequest(c, Window), cookie) + return MapSubwindowsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook MapSubwindowsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for MapSubwindows +// mapSubwindowsRequest writes a MapSubwindows request to a byte slice. +func mapSubwindowsRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 9 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// MapWindowCookie is a cookie used only for MapWindow requests. +type MapWindowCookie struct { + *xgb.Cookie +} + +// MapWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func MapWindow(c *xgb.Conn, Window Window) MapWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(mapWindowRequest(c, Window), cookie) + return MapWindowCookie{cookie} +} + +// MapWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using MapWindowCookie.Check() +func MapWindowChecked(c *xgb.Conn, Window Window) MapWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(mapWindowRequest(c, Window), cookie) + return MapWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook MapWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for MapWindow +// mapWindowRequest writes a MapWindow request to a byte slice. +func mapWindowRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 8 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// NoOperationCookie is a cookie used only for NoOperation requests. +type NoOperationCookie struct { + *xgb.Cookie +} + +// NoOperation sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func NoOperation(c *xgb.Conn) NoOperationCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(noOperationRequest(c), cookie) + return NoOperationCookie{cookie} +} + +// NoOperationChecked sends a checked request. +// If an error occurs, it can be retrieved using NoOperationCookie.Check() +func NoOperationChecked(c *xgb.Conn) NoOperationCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(noOperationRequest(c), cookie) + return NoOperationCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook NoOperationCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for NoOperation +// noOperationRequest writes a NoOperation request to a byte slice. +func noOperationRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 127 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// OpenFontCookie is a cookie used only for OpenFont requests. +type OpenFontCookie struct { + *xgb.Cookie +} + +// OpenFont sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func OpenFont(c *xgb.Conn, Fid Font, NameLen uint16, Name string) OpenFontCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(openFontRequest(c, Fid, NameLen, Name), cookie) + return OpenFontCookie{cookie} +} + +// OpenFontChecked sends a checked request. +// If an error occurs, it can be retrieved using OpenFontCookie.Check() +func OpenFontChecked(c *xgb.Conn, Fid Font, NameLen uint16, Name string) OpenFontCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(openFontRequest(c, Fid, NameLen, Name), cookie) + return OpenFontCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook OpenFontCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for OpenFont +// openFontRequest writes a OpenFont request to a byte slice. +func openFontRequest(c *xgb.Conn, Fid Font, NameLen uint16, Name string) []byte { + size := xgb.Pad((12 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 45 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Fid)) + b += 4 + + xgb.Put16(buf[b:], NameLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:NameLen]) + b += int(NameLen) + + return buf +} + +// PolyArcCookie is a cookie used only for PolyArc requests. +type PolyArcCookie struct { + *xgb.Cookie +} + +// PolyArc sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyArc(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyArcCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyArcRequest(c, Drawable, Gc, Arcs), cookie) + return PolyArcCookie{cookie} +} + +// PolyArcChecked sends a checked request. +// If an error occurs, it can be retrieved using PolyArcCookie.Check() +func PolyArcChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyArcCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyArcRequest(c, Drawable, Gc, Arcs), cookie) + return PolyArcCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyArcCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyArc +// polyArcRequest writes a PolyArc request to a byte slice. +func polyArcRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Arcs) * 12)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 68 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += ArcListBytes(buf[b:], Arcs) + + return buf +} + +// PolyFillArcCookie is a cookie used only for PolyFillArc requests. +type PolyFillArcCookie struct { + *xgb.Cookie +} + +// PolyFillArc sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyFillArc(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyFillArcCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyFillArcRequest(c, Drawable, Gc, Arcs), cookie) + return PolyFillArcCookie{cookie} +} + +// PolyFillArcChecked sends a checked request. +// If an error occurs, it can be retrieved using PolyFillArcCookie.Check() +func PolyFillArcChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyFillArcCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyFillArcRequest(c, Drawable, Gc, Arcs), cookie) + return PolyFillArcCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyFillArcCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyFillArc +// polyFillArcRequest writes a PolyFillArc request to a byte slice. +func polyFillArcRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Arcs) * 12)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 71 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += ArcListBytes(buf[b:], Arcs) + + return buf +} + +// PolyFillRectangleCookie is a cookie used only for PolyFillRectangle requests. +type PolyFillRectangleCookie struct { + *xgb.Cookie +} + +// PolyFillRectangle sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyFillRectangle(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyFillRectangleCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyFillRectangleRequest(c, Drawable, Gc, Rectangles), cookie) + return PolyFillRectangleCookie{cookie} +} + +// PolyFillRectangleChecked sends a checked request. +// If an error occurs, it can be retrieved using PolyFillRectangleCookie.Check() +func PolyFillRectangleChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyFillRectangleCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyFillRectangleRequest(c, Drawable, Gc, Rectangles), cookie) + return PolyFillRectangleCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyFillRectangleCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyFillRectangle +// polyFillRectangleRequest writes a PolyFillRectangle request to a byte slice. +func polyFillRectangleRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 70 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// PolyLineCookie is a cookie used only for PolyLine requests. +type PolyLineCookie struct { + *xgb.Cookie +} + +// PolyLine sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyLine(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyLineCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyLineRequest(c, CoordinateMode, Drawable, Gc, Points), cookie) + return PolyLineCookie{cookie} +} + +// PolyLineChecked sends a checked request. +// If an error occurs, it can be retrieved using PolyLineCookie.Check() +func PolyLineChecked(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyLineCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyLineRequest(c, CoordinateMode, Drawable, Gc, Points), cookie) + return PolyLineCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyLineCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyLine +// polyLineRequest writes a PolyLine request to a byte slice. +func polyLineRequest(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Points) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 65 // request opcode + b += 1 + + buf[b] = CoordinateMode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += PointListBytes(buf[b:], Points) + + return buf +} + +// PolyPointCookie is a cookie used only for PolyPoint requests. +type PolyPointCookie struct { + *xgb.Cookie +} + +// PolyPoint sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyPoint(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyPointCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyPointRequest(c, CoordinateMode, Drawable, Gc, Points), cookie) + return PolyPointCookie{cookie} +} + +// PolyPointChecked sends a checked request. +// If an error occurs, it can be retrieved using PolyPointCookie.Check() +func PolyPointChecked(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyPointCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyPointRequest(c, CoordinateMode, Drawable, Gc, Points), cookie) + return PolyPointCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyPointCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyPoint +// polyPointRequest writes a PolyPoint request to a byte slice. +func polyPointRequest(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Points) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 64 // request opcode + b += 1 + + buf[b] = CoordinateMode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += PointListBytes(buf[b:], Points) + + return buf +} + +// PolyRectangleCookie is a cookie used only for PolyRectangle requests. +type PolyRectangleCookie struct { + *xgb.Cookie +} + +// PolyRectangle sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyRectangle(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyRectangleCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyRectangleRequest(c, Drawable, Gc, Rectangles), cookie) + return PolyRectangleCookie{cookie} +} + +// PolyRectangleChecked sends a checked request. +// If an error occurs, it can be retrieved using PolyRectangleCookie.Check() +func PolyRectangleChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyRectangleCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyRectangleRequest(c, Drawable, Gc, Rectangles), cookie) + return PolyRectangleCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyRectangleCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyRectangle +// polyRectangleRequest writes a PolyRectangle request to a byte slice. +func polyRectangleRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 67 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// PolySegmentCookie is a cookie used only for PolySegment requests. +type PolySegmentCookie struct { + *xgb.Cookie +} + +// PolySegment sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolySegment(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Segments []Segment) PolySegmentCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polySegmentRequest(c, Drawable, Gc, Segments), cookie) + return PolySegmentCookie{cookie} +} + +// PolySegmentChecked sends a checked request. +// If an error occurs, it can be retrieved using PolySegmentCookie.Check() +func PolySegmentChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Segments []Segment) PolySegmentCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polySegmentRequest(c, Drawable, Gc, Segments), cookie) + return PolySegmentCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolySegmentCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolySegment +// polySegmentRequest writes a PolySegment request to a byte slice. +func polySegmentRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Segments []Segment) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Segments) * 8)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 66 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + b += SegmentListBytes(buf[b:], Segments) + + return buf +} + +// PolyText16Cookie is a cookie used only for PolyText16 requests. +type PolyText16Cookie struct { + *xgb.Cookie +} + +// PolyText16 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyText16(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText16Cookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyText16Request(c, Drawable, Gc, X, Y, Items), cookie) + return PolyText16Cookie{cookie} +} + +// PolyText16Checked sends a checked request. +// If an error occurs, it can be retrieved using PolyText16Cookie.Check() +func PolyText16Checked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText16Cookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyText16Request(c, Drawable, Gc, X, Y, Items), cookie) + return PolyText16Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyText16Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyText16 +// polyText16Request writes a PolyText16 request to a byte slice. +func polyText16Request(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Items) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 75 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + copy(buf[b:], Items[:len(Items)]) + b += int(len(Items)) + + return buf +} + +// PolyText8Cookie is a cookie used only for PolyText8 requests. +type PolyText8Cookie struct { + *xgb.Cookie +} + +// PolyText8 sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PolyText8(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText8Cookie { + cookie := c.NewCookie(false, false) + c.NewRequest(polyText8Request(c, Drawable, Gc, X, Y, Items), cookie) + return PolyText8Cookie{cookie} +} + +// PolyText8Checked sends a checked request. +// If an error occurs, it can be retrieved using PolyText8Cookie.Check() +func PolyText8Checked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText8Cookie { + cookie := c.NewCookie(true, false) + c.NewRequest(polyText8Request(c, Drawable, Gc, X, Y, Items), cookie) + return PolyText8Cookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PolyText8Cookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PolyText8 +// polyText8Request writes a PolyText8 request to a byte slice. +func polyText8Request(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) []byte { + size := xgb.Pad((16 + xgb.Pad((len(Items) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 74 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + copy(buf[b:], Items[:len(Items)]) + b += int(len(Items)) + + return buf +} + +// PutImageCookie is a cookie used only for PutImage requests. +type PutImageCookie struct { + *xgb.Cookie +} + +// PutImage sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PutImage(c *xgb.Conn, Format byte, Drawable Drawable, Gc Gcontext, Width uint16, Height uint16, DstX int16, DstY int16, LeftPad byte, Depth byte, Data []byte) PutImageCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(putImageRequest(c, Format, Drawable, Gc, Width, Height, DstX, DstY, LeftPad, Depth, Data), cookie) + return PutImageCookie{cookie} +} + +// PutImageChecked sends a checked request. +// If an error occurs, it can be retrieved using PutImageCookie.Check() +func PutImageChecked(c *xgb.Conn, Format byte, Drawable Drawable, Gc Gcontext, Width uint16, Height uint16, DstX int16, DstY int16, LeftPad byte, Depth byte, Data []byte) PutImageCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(putImageRequest(c, Format, Drawable, Gc, Width, Height, DstX, DstY, LeftPad, Depth, Data), cookie) + return PutImageCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PutImageCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PutImage +// putImageRequest writes a PutImage request to a byte slice. +func putImageRequest(c *xgb.Conn, Format byte, Drawable Drawable, Gc Gcontext, Width uint16, Height uint16, DstX int16, DstY int16, LeftPad byte, Depth byte, Data []byte) []byte { + size := xgb.Pad((24 + xgb.Pad((len(Data) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 72 // request opcode + b += 1 + + buf[b] = Format + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put16(buf[b:], uint16(DstX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstY)) + b += 2 + + buf[b] = LeftPad + b += 1 + + buf[b] = Depth + b += 1 + + b += 2 // padding + + copy(buf[b:], Data[:len(Data)]) + b += int(len(Data)) + + return buf +} + +// QueryBestSizeCookie is a cookie used only for QueryBestSize requests. +type QueryBestSizeCookie struct { + *xgb.Cookie +} + +// QueryBestSize sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryBestSizeCookie.Reply() +func QueryBestSize(c *xgb.Conn, Class byte, Drawable Drawable, Width uint16, Height uint16) QueryBestSizeCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryBestSizeRequest(c, Class, Drawable, Width, Height), cookie) + return QueryBestSizeCookie{cookie} +} + +// QueryBestSizeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryBestSizeUnchecked(c *xgb.Conn, Class byte, Drawable Drawable, Width uint16, Height uint16) QueryBestSizeCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryBestSizeRequest(c, Class, Drawable, Width, Height), cookie) + return QueryBestSizeCookie{cookie} +} + +// QueryBestSizeReply represents the data returned from a QueryBestSize request. +type QueryBestSizeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint16 + Height uint16 +} + +// Reply blocks and returns the reply data for a QueryBestSize request. +func (cook QueryBestSizeCookie) Reply() (*QueryBestSizeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryBestSizeReply(buf), nil +} + +// queryBestSizeReply reads a byte slice into a QueryBestSizeReply value. +func queryBestSizeReply(buf []byte) *QueryBestSizeReply { + v := new(QueryBestSizeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryBestSize +// queryBestSizeRequest writes a QueryBestSize request to a byte slice. +func queryBestSizeRequest(c *xgb.Conn, Class byte, Drawable Drawable, Width uint16, Height uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 97 // request opcode + b += 1 + + buf[b] = Class + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// QueryColorsCookie is a cookie used only for QueryColors requests. +type QueryColorsCookie struct { + *xgb.Cookie +} + +// QueryColors sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryColorsCookie.Reply() +func QueryColors(c *xgb.Conn, Cmap Colormap, Pixels []uint32) QueryColorsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryColorsRequest(c, Cmap, Pixels), cookie) + return QueryColorsCookie{cookie} +} + +// QueryColorsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryColorsUnchecked(c *xgb.Conn, Cmap Colormap, Pixels []uint32) QueryColorsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryColorsRequest(c, Cmap, Pixels), cookie) + return QueryColorsCookie{cookie} +} + +// QueryColorsReply represents the data returned from a QueryColors request. +type QueryColorsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ColorsLen uint16 + // padding: 22 bytes + Colors []Rgb // size: xgb.Pad((int(ColorsLen) * 8)) +} + +// Reply blocks and returns the reply data for a QueryColors request. +func (cook QueryColorsCookie) Reply() (*QueryColorsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryColorsReply(buf), nil +} + +// queryColorsReply reads a byte slice into a QueryColorsReply value. +func queryColorsReply(buf []byte) *QueryColorsReply { + v := new(QueryColorsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ColorsLen = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Colors = make([]Rgb, v.ColorsLen) + b += RgbReadList(buf[b:], v.Colors) + + return v +} + +// Write request to wire for QueryColors +// queryColorsRequest writes a QueryColors request to a byte slice. +func queryColorsRequest(c *xgb.Conn, Cmap Colormap, Pixels []uint32) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Pixels) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 91 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + for i := 0; i < int(len(Pixels)); i++ { + xgb.Put32(buf[b:], Pixels[i]) + b += 4 + } + + return buf +} + +// QueryExtensionCookie is a cookie used only for QueryExtension requests. +type QueryExtensionCookie struct { + *xgb.Cookie +} + +// QueryExtension sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryExtensionCookie.Reply() +func QueryExtension(c *xgb.Conn, NameLen uint16, Name string) QueryExtensionCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryExtensionRequest(c, NameLen, Name), cookie) + return QueryExtensionCookie{cookie} +} + +// QueryExtensionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryExtensionUnchecked(c *xgb.Conn, NameLen uint16, Name string) QueryExtensionCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryExtensionRequest(c, NameLen, Name), cookie) + return QueryExtensionCookie{cookie} +} + +// QueryExtensionReply represents the data returned from a QueryExtension request. +type QueryExtensionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Present bool + MajorOpcode byte + FirstEvent byte + FirstError byte +} + +// Reply blocks and returns the reply data for a QueryExtension request. +func (cook QueryExtensionCookie) Reply() (*QueryExtensionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryExtensionReply(buf), nil +} + +// queryExtensionReply reads a byte slice into a QueryExtensionReply value. +func queryExtensionReply(buf []byte) *QueryExtensionReply { + v := new(QueryExtensionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + if buf[b] == 1 { + v.Present = true + } else { + v.Present = false + } + b += 1 + + v.MajorOpcode = buf[b] + b += 1 + + v.FirstEvent = buf[b] + b += 1 + + v.FirstError = buf[b] + b += 1 + + return v +} + +// Write request to wire for QueryExtension +// queryExtensionRequest writes a QueryExtension request to a byte slice. +func queryExtensionRequest(c *xgb.Conn, NameLen uint16, Name string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 98 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], NameLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:NameLen]) + b += int(NameLen) + + return buf +} + +// QueryFontCookie is a cookie used only for QueryFont requests. +type QueryFontCookie struct { + *xgb.Cookie +} + +// QueryFont sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryFontCookie.Reply() +func QueryFont(c *xgb.Conn, Font Fontable) QueryFontCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryFontRequest(c, Font), cookie) + return QueryFontCookie{cookie} +} + +// QueryFontUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryFontUnchecked(c *xgb.Conn, Font Fontable) QueryFontCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryFontRequest(c, Font), cookie) + return QueryFontCookie{cookie} +} + +// QueryFontReply represents the data returned from a QueryFont request. +type QueryFontReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + MinBounds Charinfo + // padding: 4 bytes + MaxBounds Charinfo + // padding: 4 bytes + MinCharOrByte2 uint16 + MaxCharOrByte2 uint16 + DefaultChar uint16 + PropertiesLen uint16 + DrawDirection byte + MinByte1 byte + MaxByte1 byte + AllCharsExist bool + FontAscent int16 + FontDescent int16 + CharInfosLen uint32 + Properties []Fontprop // size: xgb.Pad((int(PropertiesLen) * 8)) + CharInfos []Charinfo // size: xgb.Pad((int(CharInfosLen) * 12)) +} + +// Reply blocks and returns the reply data for a QueryFont request. +func (cook QueryFontCookie) Reply() (*QueryFontReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryFontReply(buf), nil +} + +// queryFontReply reads a byte slice into a QueryFontReply value. +func queryFontReply(buf []byte) *QueryFontReply { + v := new(QueryFontReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MinBounds = Charinfo{} + b += CharinfoRead(buf[b:], &v.MinBounds) + + b += 4 // padding + + v.MaxBounds = Charinfo{} + b += CharinfoRead(buf[b:], &v.MaxBounds) + + b += 4 // padding + + v.MinCharOrByte2 = xgb.Get16(buf[b:]) + b += 2 + + v.MaxCharOrByte2 = xgb.Get16(buf[b:]) + b += 2 + + v.DefaultChar = xgb.Get16(buf[b:]) + b += 2 + + v.PropertiesLen = xgb.Get16(buf[b:]) + b += 2 + + v.DrawDirection = buf[b] + b += 1 + + v.MinByte1 = buf[b] + b += 1 + + v.MaxByte1 = buf[b] + b += 1 + + if buf[b] == 1 { + v.AllCharsExist = true + } else { + v.AllCharsExist = false + } + b += 1 + + v.FontAscent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.FontDescent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.CharInfosLen = xgb.Get32(buf[b:]) + b += 4 + + v.Properties = make([]Fontprop, v.PropertiesLen) + b += FontpropReadList(buf[b:], v.Properties) + + v.CharInfos = make([]Charinfo, v.CharInfosLen) + b += CharinfoReadList(buf[b:], v.CharInfos) + + return v +} + +// Write request to wire for QueryFont +// queryFontRequest writes a QueryFont request to a byte slice. +func queryFontRequest(c *xgb.Conn, Font Fontable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 47 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Font)) + b += 4 + + return buf +} + +// QueryKeymapCookie is a cookie used only for QueryKeymap requests. +type QueryKeymapCookie struct { + *xgb.Cookie +} + +// QueryKeymap sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryKeymapCookie.Reply() +func QueryKeymap(c *xgb.Conn) QueryKeymapCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryKeymapRequest(c), cookie) + return QueryKeymapCookie{cookie} +} + +// QueryKeymapUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryKeymapUnchecked(c *xgb.Conn) QueryKeymapCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryKeymapRequest(c), cookie) + return QueryKeymapCookie{cookie} +} + +// QueryKeymapReply represents the data returned from a QueryKeymap request. +type QueryKeymapReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Keys []byte // size: 32 +} + +// Reply blocks and returns the reply data for a QueryKeymap request. +func (cook QueryKeymapCookie) Reply() (*QueryKeymapReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryKeymapReply(buf), nil +} + +// queryKeymapReply reads a byte slice into a QueryKeymapReply value. +func queryKeymapReply(buf []byte) *QueryKeymapReply { + v := new(QueryKeymapReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Keys = make([]byte, 32) + copy(v.Keys[:32], buf[b:]) + b += int(32) + + return v +} + +// Write request to wire for QueryKeymap +// queryKeymapRequest writes a QueryKeymap request to a byte slice. +func queryKeymapRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 44 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryPointerCookie is a cookie used only for QueryPointer requests. +type QueryPointerCookie struct { + *xgb.Cookie +} + +// QueryPointer sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryPointerCookie.Reply() +func QueryPointer(c *xgb.Conn, Window Window) QueryPointerCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryPointerRequest(c, Window), cookie) + return QueryPointerCookie{cookie} +} + +// QueryPointerUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryPointerUnchecked(c *xgb.Conn, Window Window) QueryPointerCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryPointerRequest(c, Window), cookie) + return QueryPointerCookie{cookie} +} + +// QueryPointerReply represents the data returned from a QueryPointer request. +type QueryPointerReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + SameScreen bool + Root Window + Child Window + RootX int16 + RootY int16 + WinX int16 + WinY int16 + Mask uint16 + // padding: 2 bytes +} + +// Reply blocks and returns the reply data for a QueryPointer request. +func (cook QueryPointerCookie) Reply() (*QueryPointerReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryPointerReply(buf), nil +} + +// queryPointerReply reads a byte slice into a QueryPointerReply value. +func queryPointerReply(buf []byte) *QueryPointerReply { + v := new(QueryPointerReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.SameScreen = true + } else { + v.SameScreen = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Child = Window(xgb.Get32(buf[b:])) + b += 4 + + v.RootX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.RootY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.WinX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.WinY = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Mask = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + return v +} + +// Write request to wire for QueryPointer +// queryPointerRequest writes a QueryPointer request to a byte slice. +func queryPointerRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 38 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// QueryTextExtentsCookie is a cookie used only for QueryTextExtents requests. +type QueryTextExtentsCookie struct { + *xgb.Cookie +} + +// QueryTextExtents sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryTextExtentsCookie.Reply() +func QueryTextExtents(c *xgb.Conn, Font Fontable, String []Char2b, StringLen uint16) QueryTextExtentsCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryTextExtentsRequest(c, Font, String, StringLen), cookie) + return QueryTextExtentsCookie{cookie} +} + +// QueryTextExtentsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryTextExtentsUnchecked(c *xgb.Conn, Font Fontable, String []Char2b, StringLen uint16) QueryTextExtentsCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryTextExtentsRequest(c, Font, String, StringLen), cookie) + return QueryTextExtentsCookie{cookie} +} + +// QueryTextExtentsReply represents the data returned from a QueryTextExtents request. +type QueryTextExtentsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + DrawDirection byte + FontAscent int16 + FontDescent int16 + OverallAscent int16 + OverallDescent int16 + OverallWidth int32 + OverallLeft int32 + OverallRight int32 +} + +// Reply blocks and returns the reply data for a QueryTextExtents request. +func (cook QueryTextExtentsCookie) Reply() (*QueryTextExtentsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryTextExtentsReply(buf), nil +} + +// queryTextExtentsReply reads a byte slice into a QueryTextExtentsReply value. +func queryTextExtentsReply(buf []byte) *QueryTextExtentsReply { + v := new(QueryTextExtentsReply) + b := 1 // skip reply determinant + + v.DrawDirection = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.FontAscent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.FontDescent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.OverallAscent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.OverallDescent = int16(xgb.Get16(buf[b:])) + b += 2 + + v.OverallWidth = int32(xgb.Get32(buf[b:])) + b += 4 + + v.OverallLeft = int32(xgb.Get32(buf[b:])) + b += 4 + + v.OverallRight = int32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for QueryTextExtents +// queryTextExtentsRequest writes a QueryTextExtents request to a byte slice. +func queryTextExtentsRequest(c *xgb.Conn, Font Fontable, String []Char2b, StringLen uint16) []byte { + size := xgb.Pad((8 + xgb.Pad((len(String) * 2)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 48 // request opcode + b += 1 + + buf[b] = byte((int(StringLen) & 1)) + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Font)) + b += 4 + + b += Char2bListBytes(buf[b:], String) + + // skip writing local field: StringLen (2) :: uint16 + + return buf +} + +// QueryTreeCookie is a cookie used only for QueryTree requests. +type QueryTreeCookie struct { + *xgb.Cookie +} + +// QueryTree sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryTreeCookie.Reply() +func QueryTree(c *xgb.Conn, Window Window) QueryTreeCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(queryTreeRequest(c, Window), cookie) + return QueryTreeCookie{cookie} +} + +// QueryTreeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryTreeUnchecked(c *xgb.Conn, Window Window) QueryTreeCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(queryTreeRequest(c, Window), cookie) + return QueryTreeCookie{cookie} +} + +// QueryTreeReply represents the data returned from a QueryTree request. +type QueryTreeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Root Window + Parent Window + ChildrenLen uint16 + // padding: 14 bytes + Children []Window // size: xgb.Pad((int(ChildrenLen) * 4)) +} + +// Reply blocks and returns the reply data for a QueryTree request. +func (cook QueryTreeCookie) Reply() (*QueryTreeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryTreeReply(buf), nil +} + +// queryTreeReply reads a byte slice into a QueryTreeReply value. +func queryTreeReply(buf []byte) *QueryTreeReply { + v := new(QueryTreeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Root = Window(xgb.Get32(buf[b:])) + b += 4 + + v.Parent = Window(xgb.Get32(buf[b:])) + b += 4 + + v.ChildrenLen = xgb.Get16(buf[b:]) + b += 2 + + b += 14 // padding + + v.Children = make([]Window, v.ChildrenLen) + for i := 0; i < int(v.ChildrenLen); i++ { + v.Children[i] = Window(xgb.Get32(buf[b:])) + b += 4 + } + + return v +} + +// Write request to wire for QueryTree +// queryTreeRequest writes a QueryTree request to a byte slice. +func queryTreeRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 15 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// RecolorCursorCookie is a cookie used only for RecolorCursor requests. +type RecolorCursorCookie struct { + *xgb.Cookie +} + +// RecolorCursor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RecolorCursor(c *xgb.Conn, Cursor Cursor, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) RecolorCursorCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(recolorCursorRequest(c, Cursor, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie) + return RecolorCursorCookie{cookie} +} + +// RecolorCursorChecked sends a checked request. +// If an error occurs, it can be retrieved using RecolorCursorCookie.Check() +func RecolorCursorChecked(c *xgb.Conn, Cursor Cursor, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) RecolorCursorCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(recolorCursorRequest(c, Cursor, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie) + return RecolorCursorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RecolorCursorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RecolorCursor +// recolorCursorRequest writes a RecolorCursor request to a byte slice. +func recolorCursorRequest(c *xgb.Conn, Cursor Cursor, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + buf[b] = 96 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + xgb.Put16(buf[b:], ForeRed) + b += 2 + + xgb.Put16(buf[b:], ForeGreen) + b += 2 + + xgb.Put16(buf[b:], ForeBlue) + b += 2 + + xgb.Put16(buf[b:], BackRed) + b += 2 + + xgb.Put16(buf[b:], BackGreen) + b += 2 + + xgb.Put16(buf[b:], BackBlue) + b += 2 + + return buf +} + +// ReparentWindowCookie is a cookie used only for ReparentWindow requests. +type ReparentWindowCookie struct { + *xgb.Cookie +} + +// ReparentWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ReparentWindow(c *xgb.Conn, Window Window, Parent Window, X int16, Y int16) ReparentWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(reparentWindowRequest(c, Window, Parent, X, Y), cookie) + return ReparentWindowCookie{cookie} +} + +// ReparentWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using ReparentWindowCookie.Check() +func ReparentWindowChecked(c *xgb.Conn, Window Window, Parent Window, X int16, Y int16) ReparentWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(reparentWindowRequest(c, Window, Parent, X, Y), cookie) + return ReparentWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ReparentWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ReparentWindow +// reparentWindowRequest writes a ReparentWindow request to a byte slice. +func reparentWindowRequest(c *xgb.Conn, Window Window, Parent Window, X int16, Y int16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 7 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Parent)) + b += 4 + + xgb.Put16(buf[b:], uint16(X)) + b += 2 + + xgb.Put16(buf[b:], uint16(Y)) + b += 2 + + return buf +} + +// RotatePropertiesCookie is a cookie used only for RotateProperties requests. +type RotatePropertiesCookie struct { + *xgb.Cookie +} + +// RotateProperties sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func RotateProperties(c *xgb.Conn, Window Window, AtomsLen uint16, Delta int16, Atoms []Atom) RotatePropertiesCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(rotatePropertiesRequest(c, Window, AtomsLen, Delta, Atoms), cookie) + return RotatePropertiesCookie{cookie} +} + +// RotatePropertiesChecked sends a checked request. +// If an error occurs, it can be retrieved using RotatePropertiesCookie.Check() +func RotatePropertiesChecked(c *xgb.Conn, Window Window, AtomsLen uint16, Delta int16, Atoms []Atom) RotatePropertiesCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(rotatePropertiesRequest(c, Window, AtomsLen, Delta, Atoms), cookie) + return RotatePropertiesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook RotatePropertiesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for RotateProperties +// rotatePropertiesRequest writes a RotateProperties request to a byte slice. +func rotatePropertiesRequest(c *xgb.Conn, Window Window, AtomsLen uint16, Delta int16, Atoms []Atom) []byte { + size := xgb.Pad((12 + xgb.Pad((int(AtomsLen) * 4)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 114 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put16(buf[b:], AtomsLen) + b += 2 + + xgb.Put16(buf[b:], uint16(Delta)) + b += 2 + + for i := 0; i < int(AtomsLen); i++ { + xgb.Put32(buf[b:], uint32(Atoms[i])) + b += 4 + } + + return buf +} + +// SendEventCookie is a cookie used only for SendEvent requests. +type SendEventCookie struct { + *xgb.Cookie +} + +// SendEvent sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SendEvent(c *xgb.Conn, Propagate bool, Destination Window, EventMask uint32, Event string) SendEventCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(sendEventRequest(c, Propagate, Destination, EventMask, Event), cookie) + return SendEventCookie{cookie} +} + +// SendEventChecked sends a checked request. +// If an error occurs, it can be retrieved using SendEventCookie.Check() +func SendEventChecked(c *xgb.Conn, Propagate bool, Destination Window, EventMask uint32, Event string) SendEventCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(sendEventRequest(c, Propagate, Destination, EventMask, Event), cookie) + return SendEventCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SendEventCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SendEvent +// sendEventRequest writes a SendEvent request to a byte slice. +func sendEventRequest(c *xgb.Conn, Propagate bool, Destination Window, EventMask uint32, Event string) []byte { + size := 44 + b := 0 + buf := make([]byte, size) + + buf[b] = 25 // request opcode + b += 1 + + if Propagate { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Destination)) + b += 4 + + xgb.Put32(buf[b:], EventMask) + b += 4 + + copy(buf[b:], Event[:32]) + b += int(32) + + return buf +} + +// SetAccessControlCookie is a cookie used only for SetAccessControl requests. +type SetAccessControlCookie struct { + *xgb.Cookie +} + +// SetAccessControl sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetAccessControl(c *xgb.Conn, Mode byte) SetAccessControlCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setAccessControlRequest(c, Mode), cookie) + return SetAccessControlCookie{cookie} +} + +// SetAccessControlChecked sends a checked request. +// If an error occurs, it can be retrieved using SetAccessControlCookie.Check() +func SetAccessControlChecked(c *xgb.Conn, Mode byte) SetAccessControlCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setAccessControlRequest(c, Mode), cookie) + return SetAccessControlCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetAccessControlCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetAccessControl +// setAccessControlRequest writes a SetAccessControl request to a byte slice. +func setAccessControlRequest(c *xgb.Conn, Mode byte) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 111 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// SetClipRectanglesCookie is a cookie used only for SetClipRectangles requests. +type SetClipRectanglesCookie struct { + *xgb.Cookie +} + +// SetClipRectangles sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetClipRectangles(c *xgb.Conn, Ordering byte, Gc Gcontext, ClipXOrigin int16, ClipYOrigin int16, Rectangles []Rectangle) SetClipRectanglesCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setClipRectanglesRequest(c, Ordering, Gc, ClipXOrigin, ClipYOrigin, Rectangles), cookie) + return SetClipRectanglesCookie{cookie} +} + +// SetClipRectanglesChecked sends a checked request. +// If an error occurs, it can be retrieved using SetClipRectanglesCookie.Check() +func SetClipRectanglesChecked(c *xgb.Conn, Ordering byte, Gc Gcontext, ClipXOrigin int16, ClipYOrigin int16, Rectangles []Rectangle) SetClipRectanglesCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setClipRectanglesRequest(c, Ordering, Gc, ClipXOrigin, ClipYOrigin, Rectangles), cookie) + return SetClipRectanglesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetClipRectanglesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetClipRectangles +// setClipRectanglesRequest writes a SetClipRectangles request to a byte slice. +func setClipRectanglesRequest(c *xgb.Conn, Ordering byte, Gc Gcontext, ClipXOrigin int16, ClipYOrigin int16, Rectangles []Rectangle) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 59 // request opcode + b += 1 + + buf[b] = Ordering + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(ClipXOrigin)) + b += 2 + + xgb.Put16(buf[b:], uint16(ClipYOrigin)) + b += 2 + + b += RectangleListBytes(buf[b:], Rectangles) + + return buf +} + +// SetCloseDownModeCookie is a cookie used only for SetCloseDownMode requests. +type SetCloseDownModeCookie struct { + *xgb.Cookie +} + +// SetCloseDownMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetCloseDownMode(c *xgb.Conn, Mode byte) SetCloseDownModeCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setCloseDownModeRequest(c, Mode), cookie) + return SetCloseDownModeCookie{cookie} +} + +// SetCloseDownModeChecked sends a checked request. +// If an error occurs, it can be retrieved using SetCloseDownModeCookie.Check() +func SetCloseDownModeChecked(c *xgb.Conn, Mode byte) SetCloseDownModeCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setCloseDownModeRequest(c, Mode), cookie) + return SetCloseDownModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetCloseDownModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetCloseDownMode +// setCloseDownModeRequest writes a SetCloseDownMode request to a byte slice. +func setCloseDownModeRequest(c *xgb.Conn, Mode byte) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 112 // request opcode + b += 1 + + buf[b] = Mode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// SetDashesCookie is a cookie used only for SetDashes requests. +type SetDashesCookie struct { + *xgb.Cookie +} + +// SetDashes sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetDashes(c *xgb.Conn, Gc Gcontext, DashOffset uint16, DashesLen uint16, Dashes []byte) SetDashesCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setDashesRequest(c, Gc, DashOffset, DashesLen, Dashes), cookie) + return SetDashesCookie{cookie} +} + +// SetDashesChecked sends a checked request. +// If an error occurs, it can be retrieved using SetDashesCookie.Check() +func SetDashesChecked(c *xgb.Conn, Gc Gcontext, DashOffset uint16, DashesLen uint16, Dashes []byte) SetDashesCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setDashesRequest(c, Gc, DashOffset, DashesLen, Dashes), cookie) + return SetDashesCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetDashesCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetDashes +// setDashesRequest writes a SetDashes request to a byte slice. +func setDashesRequest(c *xgb.Conn, Gc Gcontext, DashOffset uint16, DashesLen uint16, Dashes []byte) []byte { + size := xgb.Pad((12 + xgb.Pad((int(DashesLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 58 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], DashOffset) + b += 2 + + xgb.Put16(buf[b:], DashesLen) + b += 2 + + copy(buf[b:], Dashes[:DashesLen]) + b += int(DashesLen) + + return buf +} + +// SetFontPathCookie is a cookie used only for SetFontPath requests. +type SetFontPathCookie struct { + *xgb.Cookie +} + +// SetFontPath sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetFontPath(c *xgb.Conn, FontQty uint16, Font []Str) SetFontPathCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setFontPathRequest(c, FontQty, Font), cookie) + return SetFontPathCookie{cookie} +} + +// SetFontPathChecked sends a checked request. +// If an error occurs, it can be retrieved using SetFontPathCookie.Check() +func SetFontPathChecked(c *xgb.Conn, FontQty uint16, Font []Str) SetFontPathCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setFontPathRequest(c, FontQty, Font), cookie) + return SetFontPathCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetFontPathCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetFontPath +// setFontPathRequest writes a SetFontPath request to a byte slice. +func setFontPathRequest(c *xgb.Conn, FontQty uint16, Font []Str) []byte { + size := xgb.Pad((8 + StrListSize(Font))) + b := 0 + buf := make([]byte, size) + + buf[b] = 51 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], FontQty) + b += 2 + + b += 2 // padding + + b += StrListBytes(buf[b:], Font) + + return buf +} + +// SetInputFocusCookie is a cookie used only for SetInputFocus requests. +type SetInputFocusCookie struct { + *xgb.Cookie +} + +// SetInputFocus sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetInputFocus(c *xgb.Conn, RevertTo byte, Focus Window, Time Timestamp) SetInputFocusCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setInputFocusRequest(c, RevertTo, Focus, Time), cookie) + return SetInputFocusCookie{cookie} +} + +// SetInputFocusChecked sends a checked request. +// If an error occurs, it can be retrieved using SetInputFocusCookie.Check() +func SetInputFocusChecked(c *xgb.Conn, RevertTo byte, Focus Window, Time Timestamp) SetInputFocusCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setInputFocusRequest(c, RevertTo, Focus, Time), cookie) + return SetInputFocusCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetInputFocusCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetInputFocus +// setInputFocusRequest writes a SetInputFocus request to a byte slice. +func setInputFocusRequest(c *xgb.Conn, RevertTo byte, Focus Window, Time Timestamp) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 42 // request opcode + b += 1 + + buf[b] = RevertTo + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Focus)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// SetModifierMappingCookie is a cookie used only for SetModifierMapping requests. +type SetModifierMappingCookie struct { + *xgb.Cookie +} + +// SetModifierMapping sends a checked request. +// If an error occurs, it will be returned with the reply by calling SetModifierMappingCookie.Reply() +func SetModifierMapping(c *xgb.Conn, KeycodesPerModifier byte, Keycodes []Keycode) SetModifierMappingCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(setModifierMappingRequest(c, KeycodesPerModifier, Keycodes), cookie) + return SetModifierMappingCookie{cookie} +} + +// SetModifierMappingUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetModifierMappingUnchecked(c *xgb.Conn, KeycodesPerModifier byte, Keycodes []Keycode) SetModifierMappingCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(setModifierMappingRequest(c, KeycodesPerModifier, Keycodes), cookie) + return SetModifierMappingCookie{cookie} +} + +// SetModifierMappingReply represents the data returned from a SetModifierMapping request. +type SetModifierMappingReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte +} + +// Reply blocks and returns the reply data for a SetModifierMapping request. +func (cook SetModifierMappingCookie) Reply() (*SetModifierMappingReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return setModifierMappingReply(buf), nil +} + +// setModifierMappingReply reads a byte slice into a SetModifierMappingReply value. +func setModifierMappingReply(buf []byte) *SetModifierMappingReply { + v := new(SetModifierMappingReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for SetModifierMapping +// setModifierMappingRequest writes a SetModifierMapping request to a byte slice. +func setModifierMappingRequest(c *xgb.Conn, KeycodesPerModifier byte, Keycodes []Keycode) []byte { + size := xgb.Pad((4 + xgb.Pad(((int(KeycodesPerModifier) * 8) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 118 // request opcode + b += 1 + + buf[b] = KeycodesPerModifier + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + for i := 0; i < int((int(KeycodesPerModifier) * 8)); i++ { + buf[b] = byte(Keycodes[i]) + b += 1 + } + + return buf +} + +// SetPointerMappingCookie is a cookie used only for SetPointerMapping requests. +type SetPointerMappingCookie struct { + *xgb.Cookie +} + +// SetPointerMapping sends a checked request. +// If an error occurs, it will be returned with the reply by calling SetPointerMappingCookie.Reply() +func SetPointerMapping(c *xgb.Conn, MapLen byte, Map []byte) SetPointerMappingCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(setPointerMappingRequest(c, MapLen, Map), cookie) + return SetPointerMappingCookie{cookie} +} + +// SetPointerMappingUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPointerMappingUnchecked(c *xgb.Conn, MapLen byte, Map []byte) SetPointerMappingCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(setPointerMappingRequest(c, MapLen, Map), cookie) + return SetPointerMappingCookie{cookie} +} + +// SetPointerMappingReply represents the data returned from a SetPointerMapping request. +type SetPointerMappingReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Status byte +} + +// Reply blocks and returns the reply data for a SetPointerMapping request. +func (cook SetPointerMappingCookie) Reply() (*SetPointerMappingReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return setPointerMappingReply(buf), nil +} + +// setPointerMappingReply reads a byte slice into a SetPointerMappingReply value. +func setPointerMappingReply(buf []byte) *SetPointerMappingReply { + v := new(SetPointerMappingReply) + b := 1 // skip reply determinant + + v.Status = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for SetPointerMapping +// setPointerMappingRequest writes a SetPointerMapping request to a byte slice. +func setPointerMappingRequest(c *xgb.Conn, MapLen byte, Map []byte) []byte { + size := xgb.Pad((4 + xgb.Pad((int(MapLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 116 // request opcode + b += 1 + + buf[b] = MapLen + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + copy(buf[b:], Map[:MapLen]) + b += int(MapLen) + + return buf +} + +// SetScreenSaverCookie is a cookie used only for SetScreenSaver requests. +type SetScreenSaverCookie struct { + *xgb.Cookie +} + +// SetScreenSaver sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetScreenSaver(c *xgb.Conn, Timeout int16, Interval int16, PreferBlanking byte, AllowExposures byte) SetScreenSaverCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setScreenSaverRequest(c, Timeout, Interval, PreferBlanking, AllowExposures), cookie) + return SetScreenSaverCookie{cookie} +} + +// SetScreenSaverChecked sends a checked request. +// If an error occurs, it can be retrieved using SetScreenSaverCookie.Check() +func SetScreenSaverChecked(c *xgb.Conn, Timeout int16, Interval int16, PreferBlanking byte, AllowExposures byte) SetScreenSaverCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setScreenSaverRequest(c, Timeout, Interval, PreferBlanking, AllowExposures), cookie) + return SetScreenSaverCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetScreenSaverCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetScreenSaver +// setScreenSaverRequest writes a SetScreenSaver request to a byte slice. +func setScreenSaverRequest(c *xgb.Conn, Timeout int16, Interval int16, PreferBlanking byte, AllowExposures byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 107 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put16(buf[b:], uint16(Timeout)) + b += 2 + + xgb.Put16(buf[b:], uint16(Interval)) + b += 2 + + buf[b] = PreferBlanking + b += 1 + + buf[b] = AllowExposures + b += 1 + + return buf +} + +// SetSelectionOwnerCookie is a cookie used only for SetSelectionOwner requests. +type SetSelectionOwnerCookie struct { + *xgb.Cookie +} + +// SetSelectionOwner sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetSelectionOwner(c *xgb.Conn, Owner Window, Selection Atom, Time Timestamp) SetSelectionOwnerCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(setSelectionOwnerRequest(c, Owner, Selection, Time), cookie) + return SetSelectionOwnerCookie{cookie} +} + +// SetSelectionOwnerChecked sends a checked request. +// If an error occurs, it can be retrieved using SetSelectionOwnerCookie.Check() +func SetSelectionOwnerChecked(c *xgb.Conn, Owner Window, Selection Atom, Time Timestamp) SetSelectionOwnerCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(setSelectionOwnerRequest(c, Owner, Selection, Time), cookie) + return SetSelectionOwnerCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetSelectionOwnerCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetSelectionOwner +// setSelectionOwnerRequest writes a SetSelectionOwner request to a byte slice. +func setSelectionOwnerRequest(c *xgb.Conn, Owner Window, Selection Atom, Time Timestamp) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 22 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Owner)) + b += 4 + + xgb.Put32(buf[b:], uint32(Selection)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// StoreColorsCookie is a cookie used only for StoreColors requests. +type StoreColorsCookie struct { + *xgb.Cookie +} + +// StoreColors sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func StoreColors(c *xgb.Conn, Cmap Colormap, Items []Coloritem) StoreColorsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(storeColorsRequest(c, Cmap, Items), cookie) + return StoreColorsCookie{cookie} +} + +// StoreColorsChecked sends a checked request. +// If an error occurs, it can be retrieved using StoreColorsCookie.Check() +func StoreColorsChecked(c *xgb.Conn, Cmap Colormap, Items []Coloritem) StoreColorsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(storeColorsRequest(c, Cmap, Items), cookie) + return StoreColorsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook StoreColorsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for StoreColors +// storeColorsRequest writes a StoreColors request to a byte slice. +func storeColorsRequest(c *xgb.Conn, Cmap Colormap, Items []Coloritem) []byte { + size := xgb.Pad((8 + xgb.Pad((len(Items) * 12)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 89 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + b += ColoritemListBytes(buf[b:], Items) + + return buf +} + +// StoreNamedColorCookie is a cookie used only for StoreNamedColor requests. +type StoreNamedColorCookie struct { + *xgb.Cookie +} + +// StoreNamedColor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func StoreNamedColor(c *xgb.Conn, Flags byte, Cmap Colormap, Pixel uint32, NameLen uint16, Name string) StoreNamedColorCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(storeNamedColorRequest(c, Flags, Cmap, Pixel, NameLen, Name), cookie) + return StoreNamedColorCookie{cookie} +} + +// StoreNamedColorChecked sends a checked request. +// If an error occurs, it can be retrieved using StoreNamedColorCookie.Check() +func StoreNamedColorChecked(c *xgb.Conn, Flags byte, Cmap Colormap, Pixel uint32, NameLen uint16, Name string) StoreNamedColorCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(storeNamedColorRequest(c, Flags, Cmap, Pixel, NameLen, Name), cookie) + return StoreNamedColorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook StoreNamedColorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for StoreNamedColor +// storeNamedColorRequest writes a StoreNamedColor request to a byte slice. +func storeNamedColorRequest(c *xgb.Conn, Flags byte, Cmap Colormap, Pixel uint32, NameLen uint16, Name string) []byte { + size := xgb.Pad((16 + xgb.Pad((int(NameLen) * 1)))) + b := 0 + buf := make([]byte, size) + + buf[b] = 90 // request opcode + b += 1 + + buf[b] = Flags + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + xgb.Put32(buf[b:], Pixel) + b += 4 + + xgb.Put16(buf[b:], NameLen) + b += 2 + + b += 2 // padding + + copy(buf[b:], Name[:NameLen]) + b += int(NameLen) + + return buf +} + +// TranslateCoordinatesCookie is a cookie used only for TranslateCoordinates requests. +type TranslateCoordinatesCookie struct { + *xgb.Cookie +} + +// TranslateCoordinates sends a checked request. +// If an error occurs, it will be returned with the reply by calling TranslateCoordinatesCookie.Reply() +func TranslateCoordinates(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16) TranslateCoordinatesCookie { + cookie := c.NewCookie(true, true) + c.NewRequest(translateCoordinatesRequest(c, SrcWindow, DstWindow, SrcX, SrcY), cookie) + return TranslateCoordinatesCookie{cookie} +} + +// TranslateCoordinatesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func TranslateCoordinatesUnchecked(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16) TranslateCoordinatesCookie { + cookie := c.NewCookie(false, true) + c.NewRequest(translateCoordinatesRequest(c, SrcWindow, DstWindow, SrcX, SrcY), cookie) + return TranslateCoordinatesCookie{cookie} +} + +// TranslateCoordinatesReply represents the data returned from a TranslateCoordinates request. +type TranslateCoordinatesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + SameScreen bool + Child Window + DstX int16 + DstY int16 +} + +// Reply blocks and returns the reply data for a TranslateCoordinates request. +func (cook TranslateCoordinatesCookie) Reply() (*TranslateCoordinatesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return translateCoordinatesReply(buf), nil +} + +// translateCoordinatesReply reads a byte slice into a TranslateCoordinatesReply value. +func translateCoordinatesReply(buf []byte) *TranslateCoordinatesReply { + v := new(TranslateCoordinatesReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.SameScreen = true + } else { + v.SameScreen = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Child = Window(xgb.Get32(buf[b:])) + b += 4 + + v.DstX = int16(xgb.Get16(buf[b:])) + b += 2 + + v.DstY = int16(xgb.Get16(buf[b:])) + b += 2 + + return v +} + +// Write request to wire for TranslateCoordinates +// translateCoordinatesRequest writes a TranslateCoordinates request to a byte slice. +func translateCoordinatesRequest(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + buf[b] = 40 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SrcWindow)) + b += 4 + + xgb.Put32(buf[b:], uint32(DstWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + return buf +} + +// UngrabButtonCookie is a cookie used only for UngrabButton requests. +type UngrabButtonCookie struct { + *xgb.Cookie +} + +// UngrabButton sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UngrabButton(c *xgb.Conn, Button byte, GrabWindow Window, Modifiers uint16) UngrabButtonCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(ungrabButtonRequest(c, Button, GrabWindow, Modifiers), cookie) + return UngrabButtonCookie{cookie} +} + +// UngrabButtonChecked sends a checked request. +// If an error occurs, it can be retrieved using UngrabButtonCookie.Check() +func UngrabButtonChecked(c *xgb.Conn, Button byte, GrabWindow Window, Modifiers uint16) UngrabButtonCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(ungrabButtonRequest(c, Button, GrabWindow, Modifiers), cookie) + return UngrabButtonCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UngrabButtonCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UngrabButton +// ungrabButtonRequest writes a UngrabButton request to a byte slice. +func ungrabButtonRequest(c *xgb.Conn, Button byte, GrabWindow Window, Modifiers uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 29 // request opcode + b += 1 + + buf[b] = Button + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GrabWindow)) + b += 4 + + xgb.Put16(buf[b:], Modifiers) + b += 2 + + b += 2 // padding + + return buf +} + +// UngrabKeyCookie is a cookie used only for UngrabKey requests. +type UngrabKeyCookie struct { + *xgb.Cookie +} + +// UngrabKey sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UngrabKey(c *xgb.Conn, Key Keycode, GrabWindow Window, Modifiers uint16) UngrabKeyCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(ungrabKeyRequest(c, Key, GrabWindow, Modifiers), cookie) + return UngrabKeyCookie{cookie} +} + +// UngrabKeyChecked sends a checked request. +// If an error occurs, it can be retrieved using UngrabKeyCookie.Check() +func UngrabKeyChecked(c *xgb.Conn, Key Keycode, GrabWindow Window, Modifiers uint16) UngrabKeyCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(ungrabKeyRequest(c, Key, GrabWindow, Modifiers), cookie) + return UngrabKeyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UngrabKeyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UngrabKey +// ungrabKeyRequest writes a UngrabKey request to a byte slice. +func ungrabKeyRequest(c *xgb.Conn, Key Keycode, GrabWindow Window, Modifiers uint16) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + buf[b] = 34 // request opcode + b += 1 + + buf[b] = byte(Key) + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(GrabWindow)) + b += 4 + + xgb.Put16(buf[b:], Modifiers) + b += 2 + + b += 2 // padding + + return buf +} + +// UngrabKeyboardCookie is a cookie used only for UngrabKeyboard requests. +type UngrabKeyboardCookie struct { + *xgb.Cookie +} + +// UngrabKeyboard sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UngrabKeyboard(c *xgb.Conn, Time Timestamp) UngrabKeyboardCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(ungrabKeyboardRequest(c, Time), cookie) + return UngrabKeyboardCookie{cookie} +} + +// UngrabKeyboardChecked sends a checked request. +// If an error occurs, it can be retrieved using UngrabKeyboardCookie.Check() +func UngrabKeyboardChecked(c *xgb.Conn, Time Timestamp) UngrabKeyboardCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(ungrabKeyboardRequest(c, Time), cookie) + return UngrabKeyboardCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UngrabKeyboardCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UngrabKeyboard +// ungrabKeyboardRequest writes a UngrabKeyboard request to a byte slice. +func ungrabKeyboardRequest(c *xgb.Conn, Time Timestamp) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 32 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// UngrabPointerCookie is a cookie used only for UngrabPointer requests. +type UngrabPointerCookie struct { + *xgb.Cookie +} + +// UngrabPointer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UngrabPointer(c *xgb.Conn, Time Timestamp) UngrabPointerCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(ungrabPointerRequest(c, Time), cookie) + return UngrabPointerCookie{cookie} +} + +// UngrabPointerChecked sends a checked request. +// If an error occurs, it can be retrieved using UngrabPointerCookie.Check() +func UngrabPointerChecked(c *xgb.Conn, Time Timestamp) UngrabPointerCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(ungrabPointerRequest(c, Time), cookie) + return UngrabPointerCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UngrabPointerCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UngrabPointer +// ungrabPointerRequest writes a UngrabPointer request to a byte slice. +func ungrabPointerRequest(c *xgb.Conn, Time Timestamp) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 27 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// UngrabServerCookie is a cookie used only for UngrabServer requests. +type UngrabServerCookie struct { + *xgb.Cookie +} + +// UngrabServer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UngrabServer(c *xgb.Conn) UngrabServerCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(ungrabServerRequest(c), cookie) + return UngrabServerCookie{cookie} +} + +// UngrabServerChecked sends a checked request. +// If an error occurs, it can be retrieved using UngrabServerCookie.Check() +func UngrabServerChecked(c *xgb.Conn) UngrabServerCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(ungrabServerRequest(c), cookie) + return UngrabServerCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UngrabServerCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UngrabServer +// ungrabServerRequest writes a UngrabServer request to a byte slice. +func ungrabServerRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + buf[b] = 37 // request opcode + b += 1 + + b += 1 // padding + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// UninstallColormapCookie is a cookie used only for UninstallColormap requests. +type UninstallColormapCookie struct { + *xgb.Cookie +} + +// UninstallColormap sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UninstallColormap(c *xgb.Conn, Cmap Colormap) UninstallColormapCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(uninstallColormapRequest(c, Cmap), cookie) + return UninstallColormapCookie{cookie} +} + +// UninstallColormapChecked sends a checked request. +// If an error occurs, it can be retrieved using UninstallColormapCookie.Check() +func UninstallColormapChecked(c *xgb.Conn, Cmap Colormap) UninstallColormapCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(uninstallColormapRequest(c, Cmap), cookie) + return UninstallColormapCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UninstallColormapCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UninstallColormap +// uninstallColormapRequest writes a UninstallColormap request to a byte slice. +func uninstallColormapRequest(c *xgb.Conn, Cmap Colormap) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 82 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Cmap)) + b += 4 + + return buf +} + +// UnmapSubwindowsCookie is a cookie used only for UnmapSubwindows requests. +type UnmapSubwindowsCookie struct { + *xgb.Cookie +} + +// UnmapSubwindows sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnmapSubwindows(c *xgb.Conn, Window Window) UnmapSubwindowsCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(unmapSubwindowsRequest(c, Window), cookie) + return UnmapSubwindowsCookie{cookie} +} + +// UnmapSubwindowsChecked sends a checked request. +// If an error occurs, it can be retrieved using UnmapSubwindowsCookie.Check() +func UnmapSubwindowsChecked(c *xgb.Conn, Window Window) UnmapSubwindowsCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(unmapSubwindowsRequest(c, Window), cookie) + return UnmapSubwindowsCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnmapSubwindowsCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnmapSubwindows +// unmapSubwindowsRequest writes a UnmapSubwindows request to a byte slice. +func unmapSubwindowsRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 11 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// UnmapWindowCookie is a cookie used only for UnmapWindow requests. +type UnmapWindowCookie struct { + *xgb.Cookie +} + +// UnmapWindow sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UnmapWindow(c *xgb.Conn, Window Window) UnmapWindowCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(unmapWindowRequest(c, Window), cookie) + return UnmapWindowCookie{cookie} +} + +// UnmapWindowChecked sends a checked request. +// If an error occurs, it can be retrieved using UnmapWindowCookie.Check() +func UnmapWindowChecked(c *xgb.Conn, Window Window) UnmapWindowCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(unmapWindowRequest(c, Window), cookie) + return UnmapWindowCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UnmapWindowCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UnmapWindow +// unmapWindowRequest writes a UnmapWindow request to a byte slice. +func unmapWindowRequest(c *xgb.Conn, Window Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + buf[b] = 10 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// WarpPointerCookie is a cookie used only for WarpPointer requests. +type WarpPointerCookie struct { + *xgb.Cookie +} + +// WarpPointer sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WarpPointer(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16) WarpPointerCookie { + cookie := c.NewCookie(false, false) + c.NewRequest(warpPointerRequest(c, SrcWindow, DstWindow, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY), cookie) + return WarpPointerCookie{cookie} +} + +// WarpPointerChecked sends a checked request. +// If an error occurs, it can be retrieved using WarpPointerCookie.Check() +func WarpPointerChecked(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16) WarpPointerCookie { + cookie := c.NewCookie(true, false) + c.NewRequest(warpPointerRequest(c, SrcWindow, DstWindow, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY), cookie) + return WarpPointerCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook WarpPointerCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for WarpPointer +// warpPointerRequest writes a WarpPointer request to a byte slice. +func warpPointerRequest(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + buf[b] = 41 // request opcode + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SrcWindow)) + b += 4 + + xgb.Put32(buf[b:], uint32(DstWindow)) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + xgb.Put16(buf[b:], SrcWidth) + b += 2 + + xgb.Put16(buf[b:], SrcHeight) + b += 2 + + xgb.Put16(buf[b:], uint16(DstX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DstY)) + b += 2 + + return buf +} diff --git a/vend/xgb/xproto/xproto_test.go b/vend/xgb/xproto/xproto_test.go new file mode 100644 index 0000000..f8080bf --- /dev/null +++ b/vend/xgb/xproto/xproto_test.go @@ -0,0 +1,384 @@ +package xproto + +/* + Tests for XGB. + + These tests only test the core X protocol at the moment. It isn't even + close to complete coverage (and probably never will be), but it does test + a number of different corners: requests with no replies, requests without + replies, checked (i.e., synchronous) errors, unchecked (i.e., asynchronous) + errors, and sequence number wrapping. + + There are also a couple of benchmarks that show the difference between + correctly issuing lots of requests and gathering replies and + incorrectly doing the same. (This particular difference is one of the + claimed advantages of the XCB, and therefore XGB, family.) + + In sum, these tests are more focused on testing the core xgb package itself, + rather than whether xproto has properly implemented the core X client + protocol. +*/ + +import ( + "fmt" + "log" + "math/rand" + "testing" + "time" + + "github.com/jezek/xgb" +) + +// The X connection used throughout testing. +var X *xgb.Conn + +// init initializes the X connection, seeds the RNG and starts waiting +// for events. +func init() { + var err error + + X, err = xgb.NewConn() + if err != nil { + log.Fatal(err) + } + + rand.Seed(time.Now().UnixNano()) + + go grabEvents() +} + +/******************************************************************************/ +// Tests +/******************************************************************************/ + +// TestSynchronousError purposefully causes a BadWindow error in a +// MapWindow request, and checks it synchronously. +func TestSynchronousError(t *testing.T) { + err := MapWindowChecked(X, 0).Check() // resource 0 is always invalid + if err == nil { + t.Fatalf("MapWindow: A MapWindow request that should return an " + + "error has returned a nil error.") + } + verifyMapWindowError(t, err) +} + +// TestAsynchronousError does the same thing as TestSynchronousError, but +// grabs the error asynchronously instead. +func TestAsynchronousError(t *testing.T) { + MapWindow(X, 0) // resource id 0 is always invalid + + evOrErr := waitForEvent(t, 5) + if evOrErr.ev != nil { + t.Fatalf("After issuing an erroneous MapWindow request, we have "+ + "received an event rather than an error: %s", evOrErr.ev) + } + verifyMapWindowError(t, evOrErr.err) +} + +// TestCookieBuffer issues (2^16) + n requets *without* replies to guarantee +// that the sequence number wraps and that the cookie buffer will have to +// flush itself (since there are no replies coming in to flush it). +// And just like TestSequenceWrap, we issue another request with a reply +// at the end to make sure XGB is still working properly. +func TestCookieBuffer(t *testing.T) { + n := (1 << 16) + 10 + for i := 0; i < n; i++ { + NoOperation(X) + } + TestProperty(t) +} + +// TestSequenceWrap issues (2^16) + n requests w/ replies to guarantee that the +// sequence number (which is a 16 bit integer) will wrap. It then issues one +// final request to ensure things still work properly. +func TestSequenceWrap(t *testing.T) { + n := (1 << 16) + 10 + for i := 0; i < n; i++ { + _, err := InternAtom(X, false, 5, "RANDO").Reply() + if err != nil { + t.Fatalf("InternAtom: %s", err) + } + } + TestProperty(t) +} + +// TestProperty tests whether a random value can be set and read. +func TestProperty(t *testing.T) { + propName := randString(20) // whatevs + writeVal := randString(20) + readVal, err := changeAndGetProp(propName, writeVal) + if err != nil { + t.Error(err) + } + + if readVal != writeVal { + t.Errorf("The value written, '%s', is not the same as the "+ + "value read '%s'.", writeVal, readVal) + } +} + +// TestWindowEvents creates a window, maps it, listens for configure notify +// events, issues a configure request, and checks for the appropriate +// configure notify event. +// This probably violates the notion of "test one thing and test it well," +// but testing X stuff is unique since it involves so much state. +// Each request is checked to make sure there are no errors returned. If there +// is an error, the test is failed. +// You may see a window appear quickly and then disappear. Do not be alarmed :P +// It's possible that this test will yield a false negative because we cannot +// control our environment. That is, the window manager could override the +// placement set. However, we set override redirect on the window, so the +// window manager *shouldn't* touch our window if it is well-behaved. +func TestWindowEvents(t *testing.T) { + // The geometry to set the window. + gx, gy, gw, gh := 200, 400, 1000, 300 + + wid, err := NewWindowId(X) + if err != nil { + t.Fatalf("NewId: %s", err) + } + + screen := Setup(X).DefaultScreen(X) // alias + err = CreateWindowChecked(X, screen.RootDepth, wid, screen.Root, + 0, 0, 500, 500, 0, + WindowClassInputOutput, screen.RootVisual, + CwBackPixel|CwOverrideRedirect, []uint32{0xffffffff, 1}).Check() + if err != nil { + t.Fatalf("CreateWindow: %s", err) + } + + err = MapWindowChecked(X, wid).Check() + if err != nil { + t.Fatalf("MapWindow: %s", err) + } + + // We don't listen in the CreateWindow request so that we don't get + // a MapNotify event. + err = ChangeWindowAttributesChecked(X, wid, + CwEventMask, []uint32{EventMaskStructureNotify}).Check() + if err != nil { + t.Fatalf("ChangeWindowAttributes: %s", err) + } + + err = ConfigureWindowChecked(X, wid, + ConfigWindowX|ConfigWindowY| + ConfigWindowWidth|ConfigWindowHeight, + []uint32{uint32(gx), uint32(gy), uint32(gw), uint32(gh)}).Check() + if err != nil { + t.Fatalf("ConfigureWindow: %s", err) + } + + evOrErr := waitForEvent(t, 5) + switch event := evOrErr.ev.(type) { + case ConfigureNotifyEvent: + if event.X != int16(gx) { + t.Fatalf("x was set to %d but ConfigureNotify reports %d", + gx, event.X) + } + if event.Y != int16(gy) { + t.Fatalf("y was set to %d but ConfigureNotify reports %d", + gy, event.Y) + } + if event.Width != uint16(gw) { + t.Fatalf("width was set to %d but ConfigureNotify reports %d", + gw, event.Width) + } + if event.Height != uint16(gh) { + t.Fatalf("height was set to %d but ConfigureNotify reports %d", + gh, event.Height) + } + default: + t.Fatalf("Expected a ConfigureNotifyEvent but got %T instead.", event) + } + + // Okay, clean up! + err = ChangeWindowAttributesChecked(X, wid, + CwEventMask, []uint32{0}).Check() + if err != nil { + t.Fatalf("ChangeWindowAttributes: %s", err) + } + + err = DestroyWindowChecked(X, wid).Check() + if err != nil { + t.Fatalf("DestroyWindow: %s", err) + } +} + +// Calls GetFontPath function, Issue #12 +func TestGetFontPath(t *testing.T) { + fontPathReply, err := GetFontPath(X).Reply() + if err != nil { + t.Fatalf("GetFontPath: %v", err) + } + _ = fontPathReply +} + +func TestListFonts(t *testing.T) { + listFontsReply, err := ListFonts(X, 10, 1, "*").Reply() + if err != nil { + t.Fatalf("ListFonts: %v", err) + } + _ = listFontsReply +} + +/******************************************************************************/ +// Benchmarks +/******************************************************************************/ + +// BenchmarkInternAtomsGood shows how many requests with replies +// *should* be sent and gathered from the server. Namely, send as many +// requests as you can at once, then go back and gather up all the replies. +// More importantly, this approach can exploit parallelism when +// GOMAXPROCS > 1. +// Run with `go test -run 'nomatch' -bench '.*' -cpu 1,2,6` if you have +// multiple cores to see the improvement that parallelism brings. +func BenchmarkInternAtomsGood(b *testing.B) { + b.StopTimer() + names := seqNames(b.N) + + b.StartTimer() + cookies := make([]InternAtomCookie, b.N) + for i := 0; i < b.N; i++ { + cookies[i] = InternAtom(X, false, uint16(len(names[i])), names[i]) + } + for _, cookie := range cookies { + cookie.Reply() + } +} + +// BenchmarkInternAtomsBad shows how *not* to issue a lot of requests with +// replies. Namely, each subsequent request isn't issued *until* the last +// reply is made. This implies a round trip to the X server for every +// iteration. +func BenchmarkInternAtomsPoor(b *testing.B) { + b.StopTimer() + names := seqNames(b.N) + + b.StartTimer() + for i := 0; i < b.N; i++ { + InternAtom(X, false, uint16(len(names[i])), names[i]).Reply() + } +} + +/******************************************************************************/ +// Helper functions +/******************************************************************************/ + +// changeAndGetProp sets property 'prop' with value 'val'. +// It then gets the value of that property and returns it. +// (It's used to check that the 'val' going in is the same 'val' going out.) +// It tests both requests with and without replies (GetProperty and +// ChangeProperty respectively.) +func changeAndGetProp(prop, val string) (string, error) { + setup := Setup(X) + root := setup.DefaultScreen(X).Root + + propAtom, err := InternAtom(X, false, uint16(len(prop)), prop).Reply() + if err != nil { + return "", fmt.Errorf("InternAtom: %s", err) + } + + typName := "UTF8_STRING" + typAtom, err := InternAtom(X, false, uint16(len(typName)), typName).Reply() + if err != nil { + return "", fmt.Errorf("InternAtom: %s", err) + } + + err = ChangePropertyChecked(X, PropModeReplace, root, propAtom.Atom, + typAtom.Atom, 8, uint32(len(val)), []byte(val)).Check() + if err != nil { + return "", fmt.Errorf("ChangeProperty: %s", err) + } + + reply, err := GetProperty(X, false, root, propAtom.Atom, + GetPropertyTypeAny, 0, (1<<32)-1).Reply() + if err != nil { + return "", fmt.Errorf("GetProperty: %s", err) + } + if reply.Format != 8 { + return "", fmt.Errorf("Property reply format is %d but it should be 8.", + reply.Format) + } + + return string(reply.Value), nil +} + +// verifyMapWindowError takes an error that is returned with an invalid +// MapWindow request with a window Id of 0 and makes sure the error is the +// right type and contains the correct values. +func verifyMapWindowError(t *testing.T, err error) { + switch e := err.(type) { + case WindowError: + if e.BadValue != 0 { + t.Fatalf("WindowError should report a bad value of 0 but "+ + "it reports %d instead.", e.BadValue) + } + if e.MajorOpcode != 8 { + t.Fatalf("WindowError should report a major opcode of 8 "+ + "(which is a MapWindow request), but it reports %d instead.", + e.MajorOpcode) + } + default: + t.Fatalf("Expected a WindowError but got %T instead.", e) + } +} + +// randString generates a random string of length n. +func randString(n int) string { + byts := make([]byte, n) + for i := 0; i < n; i++ { + rando := rand.Intn(53) + switch { + case rando <= 25: + byts[i] = byte(65 + rando) + case rando <= 51: + byts[i] = byte(97 + rando - 26) + default: + byts[i] = ' ' + } + } + return string(byts) +} + +// seqNames creates a slice of NAME0, NAME1, ..., NAMEN. +func seqNames(n int) []string { + names := make([]string, n) + for i := range names { + names[i] = fmt.Sprintf("NAME%d", i) + } + return names +} + +// evErr represents a value that is either an event or an error. +type evErr struct { + ev xgb.Event + err xgb.Error +} + +// channel used to pass evErrs. +var evOrErrChan = make(chan evErr, 0) + +// grabEvents is a goroutine that reads events off the wire. +// We used this instead of WaitForEvent directly in our tests so that +// we can timeout and fail a test. +func grabEvents() { + for { + ev, err := X.WaitForEvent() + evOrErrChan <- evErr{ev, err} + } +} + +// waitForEvent asks the evOrErrChan channel for an event. +// If it doesn't get an event in 'n' seconds, the current test is failed. +func waitForEvent(t *testing.T, n int) evErr { + var evOrErr evErr + + select { + case evOrErr = <-evOrErrChan: + case <-time.After(time.Second * 5): + t.Fatalf("After waiting 5 seconds for an event or an error, " + + "we have timed out.") + } + + return evOrErr +} diff --git a/vend/xgb/xselinux/xselinux.go b/vend/xgb/xselinux/xselinux.go new file mode 100644 index 0000000..5b383cc --- /dev/null +++ b/vend/xgb/xselinux/xselinux.go @@ -0,0 +1,2267 @@ +// Package xselinux is the X client API for the SELinux extension. +package xselinux + +// This file is automatically generated from xselinux.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the SELinux extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 7, "SELinux").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named SELinux could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["SELinux"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["SELinux"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["SELinux"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["SELinux"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["SELinux"] = make(map[int]xgb.NewErrorFun) +} + +type ListItem struct { + Name xproto.Atom + ObjectContextLen uint32 + DataContextLen uint32 + ObjectContext string // size: xgb.Pad((int(ObjectContextLen) * 1)) + // alignment gap to multiple of 4 + DataContext string // size: xgb.Pad((int(DataContextLen) * 1)) + // alignment gap to multiple of 4 +} + +// ListItemRead reads a byte slice into a ListItem value. +func ListItemRead(buf []byte, v *ListItem) int { + b := 0 + + v.Name = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.ObjectContextLen = xgb.Get32(buf[b:]) + b += 4 + + v.DataContextLen = xgb.Get32(buf[b:]) + b += 4 + + { + byteString := make([]byte, v.ObjectContextLen) + copy(byteString[:v.ObjectContextLen], buf[b:]) + v.ObjectContext = string(byteString) + b += int(v.ObjectContextLen) + } + + b = (b + 3) & ^3 // alignment gap + + { + byteString := make([]byte, v.DataContextLen) + copy(byteString[:v.DataContextLen], buf[b:]) + v.DataContext = string(byteString) + b += int(v.DataContextLen) + } + + b = (b + 3) & ^3 // alignment gap + + return b +} + +// ListItemReadList reads a byte slice into a list of ListItem values. +func ListItemReadList(buf []byte, dest []ListItem) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ListItem{} + b += ListItemRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ListItem value to a byte slice. +func (v ListItem) Bytes() []byte { + buf := make([]byte, ((((12 + xgb.Pad((int(v.ObjectContextLen) * 1))) + 4) + xgb.Pad((int(v.DataContextLen) * 1))) + 4)) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Name)) + b += 4 + + xgb.Put32(buf[b:], v.ObjectContextLen) + b += 4 + + xgb.Put32(buf[b:], v.DataContextLen) + b += 4 + + copy(buf[b:], v.ObjectContext[:v.ObjectContextLen]) + b += int(v.ObjectContextLen) + + b = (b + 3) & ^3 // alignment gap + + copy(buf[b:], v.DataContext[:v.DataContextLen]) + b += int(v.DataContextLen) + + b = (b + 3) & ^3 // alignment gap + + return buf[:b] +} + +// ListItemListBytes writes a list of ListItem values to a byte slice. +func ListItemListBytes(buf []byte, list []ListItem) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ListItemListSize computes the size (bytes) of a list of ListItem values. +func ListItemListSize(list []ListItem) int { + size := 0 + for _, item := range list { + size += ((((12 + xgb.Pad((int(item.ObjectContextLen) * 1))) + 4) + xgb.Pad((int(item.DataContextLen) * 1))) + 4) + } + return size +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// GetClientContextCookie is a cookie used only for GetClientContext requests. +type GetClientContextCookie struct { + *xgb.Cookie +} + +// GetClientContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetClientContextCookie.Reply() +func GetClientContext(c *xgb.Conn, Resource uint32) GetClientContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetClientContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getClientContextRequest(c, Resource), cookie) + return GetClientContextCookie{cookie} +} + +// GetClientContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetClientContextUnchecked(c *xgb.Conn, Resource uint32) GetClientContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetClientContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getClientContextRequest(c, Resource), cookie) + return GetClientContextCookie{cookie} +} + +// GetClientContextReply represents the data returned from a GetClientContext request. +type GetClientContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetClientContext request. +func (cook GetClientContextCookie) Reply() (*GetClientContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getClientContextReply(buf), nil +} + +// getClientContextReply reads a byte slice into a GetClientContextReply value. +func getClientContextReply(buf []byte) *GetClientContextReply { + v := new(GetClientContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetClientContext +// getClientContextRequest writes a GetClientContext request to a byte slice. +func getClientContextRequest(c *xgb.Conn, Resource uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 22 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Resource) + b += 4 + + return buf +} + +// GetDeviceContextCookie is a cookie used only for GetDeviceContext requests. +type GetDeviceContextCookie struct { + *xgb.Cookie +} + +// GetDeviceContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDeviceContextCookie.Reply() +func GetDeviceContext(c *xgb.Conn, Device uint32) GetDeviceContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetDeviceContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDeviceContextRequest(c, Device), cookie) + return GetDeviceContextCookie{cookie} +} + +// GetDeviceContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDeviceContextUnchecked(c *xgb.Conn, Device uint32) GetDeviceContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetDeviceContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDeviceContextRequest(c, Device), cookie) + return GetDeviceContextCookie{cookie} +} + +// GetDeviceContextReply represents the data returned from a GetDeviceContext request. +type GetDeviceContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetDeviceContext request. +func (cook GetDeviceContextCookie) Reply() (*GetDeviceContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDeviceContextReply(buf), nil +} + +// getDeviceContextReply reads a byte slice into a GetDeviceContextReply value. +func getDeviceContextReply(buf []byte) *GetDeviceContextReply { + v := new(GetDeviceContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetDeviceContext +// getDeviceContextRequest writes a GetDeviceContext request to a byte slice. +func getDeviceContextRequest(c *xgb.Conn, Device uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Device) + b += 4 + + return buf +} + +// GetDeviceCreateContextCookie is a cookie used only for GetDeviceCreateContext requests. +type GetDeviceCreateContextCookie struct { + *xgb.Cookie +} + +// GetDeviceCreateContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetDeviceCreateContextCookie.Reply() +func GetDeviceCreateContext(c *xgb.Conn) GetDeviceCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetDeviceCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getDeviceCreateContextRequest(c), cookie) + return GetDeviceCreateContextCookie{cookie} +} + +// GetDeviceCreateContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetDeviceCreateContextUnchecked(c *xgb.Conn) GetDeviceCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetDeviceCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getDeviceCreateContextRequest(c), cookie) + return GetDeviceCreateContextCookie{cookie} +} + +// GetDeviceCreateContextReply represents the data returned from a GetDeviceCreateContext request. +type GetDeviceCreateContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetDeviceCreateContext request. +func (cook GetDeviceCreateContextCookie) Reply() (*GetDeviceCreateContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getDeviceCreateContextReply(buf), nil +} + +// getDeviceCreateContextReply reads a byte slice into a GetDeviceCreateContextReply value. +func getDeviceCreateContextReply(buf []byte) *GetDeviceCreateContextReply { + v := new(GetDeviceCreateContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetDeviceCreateContext +// getDeviceCreateContextRequest writes a GetDeviceCreateContext request to a byte slice. +func getDeviceCreateContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetPropertyContextCookie is a cookie used only for GetPropertyContext requests. +type GetPropertyContextCookie struct { + *xgb.Cookie +} + +// GetPropertyContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPropertyContextCookie.Reply() +func GetPropertyContext(c *xgb.Conn, Window xproto.Window, Property xproto.Atom) GetPropertyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPropertyContextRequest(c, Window, Property), cookie) + return GetPropertyContextCookie{cookie} +} + +// GetPropertyContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPropertyContextUnchecked(c *xgb.Conn, Window xproto.Window, Property xproto.Atom) GetPropertyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPropertyContextRequest(c, Window, Property), cookie) + return GetPropertyContextCookie{cookie} +} + +// GetPropertyContextReply represents the data returned from a GetPropertyContext request. +type GetPropertyContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetPropertyContext request. +func (cook GetPropertyContextCookie) Reply() (*GetPropertyContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPropertyContextReply(buf), nil +} + +// getPropertyContextReply reads a byte slice into a GetPropertyContextReply value. +func getPropertyContextReply(buf []byte) *GetPropertyContextReply { + v := new(GetPropertyContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetPropertyContext +// getPropertyContextRequest writes a GetPropertyContext request to a byte slice. +func getPropertyContextRequest(c *xgb.Conn, Window xproto.Window, Property xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// GetPropertyCreateContextCookie is a cookie used only for GetPropertyCreateContext requests. +type GetPropertyCreateContextCookie struct { + *xgb.Cookie +} + +// GetPropertyCreateContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPropertyCreateContextCookie.Reply() +func GetPropertyCreateContext(c *xgb.Conn) GetPropertyCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPropertyCreateContextRequest(c), cookie) + return GetPropertyCreateContextCookie{cookie} +} + +// GetPropertyCreateContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPropertyCreateContextUnchecked(c *xgb.Conn) GetPropertyCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPropertyCreateContextRequest(c), cookie) + return GetPropertyCreateContextCookie{cookie} +} + +// GetPropertyCreateContextReply represents the data returned from a GetPropertyCreateContext request. +type GetPropertyCreateContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetPropertyCreateContext request. +func (cook GetPropertyCreateContextCookie) Reply() (*GetPropertyCreateContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPropertyCreateContextReply(buf), nil +} + +// getPropertyCreateContextReply reads a byte slice into a GetPropertyCreateContextReply value. +func getPropertyCreateContextReply(buf []byte) *GetPropertyCreateContextReply { + v := new(GetPropertyCreateContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetPropertyCreateContext +// getPropertyCreateContextRequest writes a GetPropertyCreateContext request to a byte slice. +func getPropertyCreateContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetPropertyDataContextCookie is a cookie used only for GetPropertyDataContext requests. +type GetPropertyDataContextCookie struct { + *xgb.Cookie +} + +// GetPropertyDataContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPropertyDataContextCookie.Reply() +func GetPropertyDataContext(c *xgb.Conn, Window xproto.Window, Property xproto.Atom) GetPropertyDataContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyDataContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPropertyDataContextRequest(c, Window, Property), cookie) + return GetPropertyDataContextCookie{cookie} +} + +// GetPropertyDataContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPropertyDataContextUnchecked(c *xgb.Conn, Window xproto.Window, Property xproto.Atom) GetPropertyDataContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyDataContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPropertyDataContextRequest(c, Window, Property), cookie) + return GetPropertyDataContextCookie{cookie} +} + +// GetPropertyDataContextReply represents the data returned from a GetPropertyDataContext request. +type GetPropertyDataContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetPropertyDataContext request. +func (cook GetPropertyDataContextCookie) Reply() (*GetPropertyDataContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPropertyDataContextReply(buf), nil +} + +// getPropertyDataContextReply reads a byte slice into a GetPropertyDataContextReply value. +func getPropertyDataContextReply(buf []byte) *GetPropertyDataContextReply { + v := new(GetPropertyDataContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetPropertyDataContext +// getPropertyDataContextRequest writes a GetPropertyDataContext request to a byte slice. +func getPropertyDataContextRequest(c *xgb.Conn, Window xproto.Window, Property xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Property)) + b += 4 + + return buf +} + +// GetPropertyUseContextCookie is a cookie used only for GetPropertyUseContext requests. +type GetPropertyUseContextCookie struct { + *xgb.Cookie +} + +// GetPropertyUseContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPropertyUseContextCookie.Reply() +func GetPropertyUseContext(c *xgb.Conn) GetPropertyUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPropertyUseContextRequest(c), cookie) + return GetPropertyUseContextCookie{cookie} +} + +// GetPropertyUseContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPropertyUseContextUnchecked(c *xgb.Conn) GetPropertyUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetPropertyUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPropertyUseContextRequest(c), cookie) + return GetPropertyUseContextCookie{cookie} +} + +// GetPropertyUseContextReply represents the data returned from a GetPropertyUseContext request. +type GetPropertyUseContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetPropertyUseContext request. +func (cook GetPropertyUseContextCookie) Reply() (*GetPropertyUseContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPropertyUseContextReply(buf), nil +} + +// getPropertyUseContextReply reads a byte slice into a GetPropertyUseContextReply value. +func getPropertyUseContextReply(buf []byte) *GetPropertyUseContextReply { + v := new(GetPropertyUseContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetPropertyUseContext +// getPropertyUseContextRequest writes a GetPropertyUseContext request to a byte slice. +func getPropertyUseContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetSelectionContextCookie is a cookie used only for GetSelectionContext requests. +type GetSelectionContextCookie struct { + *xgb.Cookie +} + +// GetSelectionContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetSelectionContextCookie.Reply() +func GetSelectionContext(c *xgb.Conn, Selection xproto.Atom) GetSelectionContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getSelectionContextRequest(c, Selection), cookie) + return GetSelectionContextCookie{cookie} +} + +// GetSelectionContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetSelectionContextUnchecked(c *xgb.Conn, Selection xproto.Atom) GetSelectionContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getSelectionContextRequest(c, Selection), cookie) + return GetSelectionContextCookie{cookie} +} + +// GetSelectionContextReply represents the data returned from a GetSelectionContext request. +type GetSelectionContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetSelectionContext request. +func (cook GetSelectionContextCookie) Reply() (*GetSelectionContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getSelectionContextReply(buf), nil +} + +// getSelectionContextReply reads a byte slice into a GetSelectionContextReply value. +func getSelectionContextReply(buf []byte) *GetSelectionContextReply { + v := new(GetSelectionContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetSelectionContext +// getSelectionContextRequest writes a GetSelectionContext request to a byte slice. +func getSelectionContextRequest(c *xgb.Conn, Selection xproto.Atom) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Selection)) + b += 4 + + return buf +} + +// GetSelectionCreateContextCookie is a cookie used only for GetSelectionCreateContext requests. +type GetSelectionCreateContextCookie struct { + *xgb.Cookie +} + +// GetSelectionCreateContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetSelectionCreateContextCookie.Reply() +func GetSelectionCreateContext(c *xgb.Conn) GetSelectionCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getSelectionCreateContextRequest(c), cookie) + return GetSelectionCreateContextCookie{cookie} +} + +// GetSelectionCreateContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetSelectionCreateContextUnchecked(c *xgb.Conn) GetSelectionCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getSelectionCreateContextRequest(c), cookie) + return GetSelectionCreateContextCookie{cookie} +} + +// GetSelectionCreateContextReply represents the data returned from a GetSelectionCreateContext request. +type GetSelectionCreateContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetSelectionCreateContext request. +func (cook GetSelectionCreateContextCookie) Reply() (*GetSelectionCreateContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getSelectionCreateContextReply(buf), nil +} + +// getSelectionCreateContextReply reads a byte slice into a GetSelectionCreateContextReply value. +func getSelectionCreateContextReply(buf []byte) *GetSelectionCreateContextReply { + v := new(GetSelectionCreateContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetSelectionCreateContext +// getSelectionCreateContextRequest writes a GetSelectionCreateContext request to a byte slice. +func getSelectionCreateContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetSelectionDataContextCookie is a cookie used only for GetSelectionDataContext requests. +type GetSelectionDataContextCookie struct { + *xgb.Cookie +} + +// GetSelectionDataContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetSelectionDataContextCookie.Reply() +func GetSelectionDataContext(c *xgb.Conn, Selection xproto.Atom) GetSelectionDataContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionDataContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getSelectionDataContextRequest(c, Selection), cookie) + return GetSelectionDataContextCookie{cookie} +} + +// GetSelectionDataContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetSelectionDataContextUnchecked(c *xgb.Conn, Selection xproto.Atom) GetSelectionDataContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionDataContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getSelectionDataContextRequest(c, Selection), cookie) + return GetSelectionDataContextCookie{cookie} +} + +// GetSelectionDataContextReply represents the data returned from a GetSelectionDataContext request. +type GetSelectionDataContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetSelectionDataContext request. +func (cook GetSelectionDataContextCookie) Reply() (*GetSelectionDataContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getSelectionDataContextReply(buf), nil +} + +// getSelectionDataContextReply reads a byte slice into a GetSelectionDataContextReply value. +func getSelectionDataContextReply(buf []byte) *GetSelectionDataContextReply { + v := new(GetSelectionDataContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetSelectionDataContext +// getSelectionDataContextRequest writes a GetSelectionDataContext request to a byte slice. +func getSelectionDataContextRequest(c *xgb.Conn, Selection xproto.Atom) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 20 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Selection)) + b += 4 + + return buf +} + +// GetSelectionUseContextCookie is a cookie used only for GetSelectionUseContext requests. +type GetSelectionUseContextCookie struct { + *xgb.Cookie +} + +// GetSelectionUseContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetSelectionUseContextCookie.Reply() +func GetSelectionUseContext(c *xgb.Conn) GetSelectionUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getSelectionUseContextRequest(c), cookie) + return GetSelectionUseContextCookie{cookie} +} + +// GetSelectionUseContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetSelectionUseContextUnchecked(c *xgb.Conn) GetSelectionUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetSelectionUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getSelectionUseContextRequest(c), cookie) + return GetSelectionUseContextCookie{cookie} +} + +// GetSelectionUseContextReply represents the data returned from a GetSelectionUseContext request. +type GetSelectionUseContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetSelectionUseContext request. +func (cook GetSelectionUseContextCookie) Reply() (*GetSelectionUseContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getSelectionUseContextReply(buf), nil +} + +// getSelectionUseContextReply reads a byte slice into a GetSelectionUseContextReply value. +func getSelectionUseContextReply(buf []byte) *GetSelectionUseContextReply { + v := new(GetSelectionUseContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetSelectionUseContext +// getSelectionUseContextRequest writes a GetSelectionUseContext request to a byte slice. +func getSelectionUseContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// GetWindowContextCookie is a cookie used only for GetWindowContext requests. +type GetWindowContextCookie struct { + *xgb.Cookie +} + +// GetWindowContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetWindowContextCookie.Reply() +func GetWindowContext(c *xgb.Conn, Window xproto.Window) GetWindowContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetWindowContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getWindowContextRequest(c, Window), cookie) + return GetWindowContextCookie{cookie} +} + +// GetWindowContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetWindowContextUnchecked(c *xgb.Conn, Window xproto.Window) GetWindowContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetWindowContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getWindowContextRequest(c, Window), cookie) + return GetWindowContextCookie{cookie} +} + +// GetWindowContextReply represents the data returned from a GetWindowContext request. +type GetWindowContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetWindowContext request. +func (cook GetWindowContextCookie) Reply() (*GetWindowContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getWindowContextReply(buf), nil +} + +// getWindowContextReply reads a byte slice into a GetWindowContextReply value. +func getWindowContextReply(buf []byte) *GetWindowContextReply { + v := new(GetWindowContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetWindowContext +// getWindowContextRequest writes a GetWindowContext request to a byte slice. +func getWindowContextRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// GetWindowCreateContextCookie is a cookie used only for GetWindowCreateContext requests. +type GetWindowCreateContextCookie struct { + *xgb.Cookie +} + +// GetWindowCreateContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetWindowCreateContextCookie.Reply() +func GetWindowCreateContext(c *xgb.Conn) GetWindowCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetWindowCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getWindowCreateContextRequest(c), cookie) + return GetWindowCreateContextCookie{cookie} +} + +// GetWindowCreateContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetWindowCreateContextUnchecked(c *xgb.Conn) GetWindowCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'GetWindowCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getWindowCreateContextRequest(c), cookie) + return GetWindowCreateContextCookie{cookie} +} + +// GetWindowCreateContextReply represents the data returned from a GetWindowCreateContext request. +type GetWindowCreateContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ContextLen uint32 + // padding: 20 bytes + Context string // size: xgb.Pad((int(ContextLen) * 1)) +} + +// Reply blocks and returns the reply data for a GetWindowCreateContext request. +func (cook GetWindowCreateContextCookie) Reply() (*GetWindowCreateContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getWindowCreateContextReply(buf), nil +} + +// getWindowCreateContextReply reads a byte slice into a GetWindowCreateContextReply value. +func getWindowCreateContextReply(buf []byte) *GetWindowCreateContextReply { + v := new(GetWindowCreateContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ContextLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + { + byteString := make([]byte, v.ContextLen) + copy(byteString[:v.ContextLen], buf[b:]) + v.Context = string(byteString) + b += int(v.ContextLen) + } + + return v +} + +// Write request to wire for GetWindowCreateContext +// getWindowCreateContextRequest writes a GetWindowCreateContext request to a byte slice. +func getWindowCreateContextRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// ListPropertiesCookie is a cookie used only for ListProperties requests. +type ListPropertiesCookie struct { + *xgb.Cookie +} + +// ListProperties sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListPropertiesCookie.Reply() +func ListProperties(c *xgb.Conn, Window xproto.Window) ListPropertiesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'ListProperties' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listPropertiesRequest(c, Window), cookie) + return ListPropertiesCookie{cookie} +} + +// ListPropertiesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListPropertiesUnchecked(c *xgb.Conn, Window xproto.Window) ListPropertiesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'ListProperties' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listPropertiesRequest(c, Window), cookie) + return ListPropertiesCookie{cookie} +} + +// ListPropertiesReply represents the data returned from a ListProperties request. +type ListPropertiesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + PropertiesLen uint32 + // padding: 20 bytes + Properties []ListItem // size: ListItemListSize(Properties) +} + +// Reply blocks and returns the reply data for a ListProperties request. +func (cook ListPropertiesCookie) Reply() (*ListPropertiesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listPropertiesReply(buf), nil +} + +// listPropertiesReply reads a byte slice into a ListPropertiesReply value. +func listPropertiesReply(buf []byte) *ListPropertiesReply { + v := new(ListPropertiesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.PropertiesLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Properties = make([]ListItem, v.PropertiesLen) + b += ListItemReadList(buf[b:], v.Properties) + + return v +} + +// Write request to wire for ListProperties +// listPropertiesRequest writes a ListProperties request to a byte slice. +func listPropertiesRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// ListSelectionsCookie is a cookie used only for ListSelections requests. +type ListSelectionsCookie struct { + *xgb.Cookie +} + +// ListSelections sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListSelectionsCookie.Reply() +func ListSelections(c *xgb.Conn) ListSelectionsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'ListSelections' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listSelectionsRequest(c), cookie) + return ListSelectionsCookie{cookie} +} + +// ListSelectionsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListSelectionsUnchecked(c *xgb.Conn) ListSelectionsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'ListSelections' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listSelectionsRequest(c), cookie) + return ListSelectionsCookie{cookie} +} + +// ListSelectionsReply represents the data returned from a ListSelections request. +type ListSelectionsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + SelectionsLen uint32 + // padding: 20 bytes + Selections []ListItem // size: ListItemListSize(Selections) +} + +// Reply blocks and returns the reply data for a ListSelections request. +func (cook ListSelectionsCookie) Reply() (*ListSelectionsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listSelectionsReply(buf), nil +} + +// listSelectionsReply reads a byte slice into a ListSelectionsReply value. +func listSelectionsReply(buf []byte) *ListSelectionsReply { + v := new(ListSelectionsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.SelectionsLen = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Selections = make([]ListItem, v.SelectionsLen) + b += ListItemReadList(buf[b:], v.Selections) + + return v +} + +// Write request to wire for ListSelections +// listSelectionsRequest writes a ListSelections request to a byte slice. +func listSelectionsRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 21 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn, ClientMajor byte, ClientMinor byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, ClientMajor, ClientMinor), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn, ClientMajor byte, ClientMinor byte) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, ClientMajor, ClientMinor), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ServerMajor uint16 + ServerMinor uint16 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ServerMajor = xgb.Get16(buf[b:]) + b += 2 + + v.ServerMinor = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, ClientMajor byte, ClientMinor byte) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = ClientMajor + b += 1 + + buf[b] = ClientMinor + b += 1 + + return buf +} + +// SetDeviceContextCookie is a cookie used only for SetDeviceContext requests. +type SetDeviceContextCookie struct { + *xgb.Cookie +} + +// SetDeviceContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetDeviceContext(c *xgb.Conn, Device uint32, ContextLen uint32, Context string) SetDeviceContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetDeviceContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setDeviceContextRequest(c, Device, ContextLen, Context), cookie) + return SetDeviceContextCookie{cookie} +} + +// SetDeviceContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetDeviceContextCookie.Check() +func SetDeviceContextChecked(c *xgb.Conn, Device uint32, ContextLen uint32, Context string) SetDeviceContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetDeviceContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setDeviceContextRequest(c, Device, ContextLen, Context), cookie) + return SetDeviceContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetDeviceContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetDeviceContext +// setDeviceContextRequest writes a SetDeviceContext request to a byte slice. +func setDeviceContextRequest(c *xgb.Conn, Device uint32, ContextLen uint32, Context string) []byte { + size := xgb.Pad((12 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], Device) + b += 4 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} + +// SetDeviceCreateContextCookie is a cookie used only for SetDeviceCreateContext requests. +type SetDeviceCreateContextCookie struct { + *xgb.Cookie +} + +// SetDeviceCreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetDeviceCreateContext(c *xgb.Conn, ContextLen uint32, Context string) SetDeviceCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetDeviceCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setDeviceCreateContextRequest(c, ContextLen, Context), cookie) + return SetDeviceCreateContextCookie{cookie} +} + +// SetDeviceCreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetDeviceCreateContextCookie.Check() +func SetDeviceCreateContextChecked(c *xgb.Conn, ContextLen uint32, Context string) SetDeviceCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetDeviceCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setDeviceCreateContextRequest(c, ContextLen, Context), cookie) + return SetDeviceCreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetDeviceCreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetDeviceCreateContext +// setDeviceCreateContextRequest writes a SetDeviceCreateContext request to a byte slice. +func setDeviceCreateContextRequest(c *xgb.Conn, ContextLen uint32, Context string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} + +// SetPropertyCreateContextCookie is a cookie used only for SetPropertyCreateContext requests. +type SetPropertyCreateContextCookie struct { + *xgb.Cookie +} + +// SetPropertyCreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPropertyCreateContext(c *xgb.Conn, ContextLen uint32, Context string) SetPropertyCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetPropertyCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPropertyCreateContextRequest(c, ContextLen, Context), cookie) + return SetPropertyCreateContextCookie{cookie} +} + +// SetPropertyCreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPropertyCreateContextCookie.Check() +func SetPropertyCreateContextChecked(c *xgb.Conn, ContextLen uint32, Context string) SetPropertyCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetPropertyCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPropertyCreateContextRequest(c, ContextLen, Context), cookie) + return SetPropertyCreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPropertyCreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPropertyCreateContext +// setPropertyCreateContextRequest writes a SetPropertyCreateContext request to a byte slice. +func setPropertyCreateContextRequest(c *xgb.Conn, ContextLen uint32, Context string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} + +// SetPropertyUseContextCookie is a cookie used only for SetPropertyUseContext requests. +type SetPropertyUseContextCookie struct { + *xgb.Cookie +} + +// SetPropertyUseContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPropertyUseContext(c *xgb.Conn, ContextLen uint32, Context string) SetPropertyUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetPropertyUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPropertyUseContextRequest(c, ContextLen, Context), cookie) + return SetPropertyUseContextCookie{cookie} +} + +// SetPropertyUseContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPropertyUseContextCookie.Check() +func SetPropertyUseContextChecked(c *xgb.Conn, ContextLen uint32, Context string) SetPropertyUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetPropertyUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPropertyUseContextRequest(c, ContextLen, Context), cookie) + return SetPropertyUseContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPropertyUseContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPropertyUseContext +// setPropertyUseContextRequest writes a SetPropertyUseContext request to a byte slice. +func setPropertyUseContextRequest(c *xgb.Conn, ContextLen uint32, Context string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} + +// SetSelectionCreateContextCookie is a cookie used only for SetSelectionCreateContext requests. +type SetSelectionCreateContextCookie struct { + *xgb.Cookie +} + +// SetSelectionCreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetSelectionCreateContext(c *xgb.Conn, ContextLen uint32, Context string) SetSelectionCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetSelectionCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setSelectionCreateContextRequest(c, ContextLen, Context), cookie) + return SetSelectionCreateContextCookie{cookie} +} + +// SetSelectionCreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetSelectionCreateContextCookie.Check() +func SetSelectionCreateContextChecked(c *xgb.Conn, ContextLen uint32, Context string) SetSelectionCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetSelectionCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setSelectionCreateContextRequest(c, ContextLen, Context), cookie) + return SetSelectionCreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetSelectionCreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetSelectionCreateContext +// setSelectionCreateContextRequest writes a SetSelectionCreateContext request to a byte slice. +func setSelectionCreateContextRequest(c *xgb.Conn, ContextLen uint32, Context string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} + +// SetSelectionUseContextCookie is a cookie used only for SetSelectionUseContext requests. +type SetSelectionUseContextCookie struct { + *xgb.Cookie +} + +// SetSelectionUseContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetSelectionUseContext(c *xgb.Conn, ContextLen uint32, Context string) SetSelectionUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetSelectionUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setSelectionUseContextRequest(c, ContextLen, Context), cookie) + return SetSelectionUseContextCookie{cookie} +} + +// SetSelectionUseContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetSelectionUseContextCookie.Check() +func SetSelectionUseContextChecked(c *xgb.Conn, ContextLen uint32, Context string) SetSelectionUseContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetSelectionUseContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setSelectionUseContextRequest(c, ContextLen, Context), cookie) + return SetSelectionUseContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetSelectionUseContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetSelectionUseContext +// setSelectionUseContextRequest writes a SetSelectionUseContext request to a byte slice. +func setSelectionUseContextRequest(c *xgb.Conn, ContextLen uint32, Context string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} + +// SetWindowCreateContextCookie is a cookie used only for SetWindowCreateContext requests. +type SetWindowCreateContextCookie struct { + *xgb.Cookie +} + +// SetWindowCreateContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetWindowCreateContext(c *xgb.Conn, ContextLen uint32, Context string) SetWindowCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetWindowCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setWindowCreateContextRequest(c, ContextLen, Context), cookie) + return SetWindowCreateContextCookie{cookie} +} + +// SetWindowCreateContextChecked sends a checked request. +// If an error occurs, it can be retrieved using SetWindowCreateContextCookie.Check() +func SetWindowCreateContextChecked(c *xgb.Conn, ContextLen uint32, Context string) SetWindowCreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["SELinux"]; !ok { + panic("Cannot issue request 'SetWindowCreateContext' using the uninitialized extension 'SELinux'. xselinux.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setWindowCreateContextRequest(c, ContextLen, Context), cookie) + return SetWindowCreateContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetWindowCreateContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetWindowCreateContext +// setWindowCreateContextRequest writes a SetWindowCreateContext request to a byte slice. +func setWindowCreateContextRequest(c *xgb.Conn, ContextLen uint32, Context string) []byte { + size := xgb.Pad((8 + xgb.Pad((int(ContextLen) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["SELinux"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], ContextLen) + b += 4 + + copy(buf[b:], Context[:ContextLen]) + b += int(ContextLen) + + return buf +} diff --git a/vend/xgb/xtest/xtest.go b/vend/xgb/xtest/xtest.go new file mode 100644 index 0000000..c11cfc6 --- /dev/null +++ b/vend/xgb/xtest/xtest.go @@ -0,0 +1,416 @@ +// Package xtest is the X client API for the XTEST extension. +package xtest + +// This file is automatically generated from xtest.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XTEST extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 5, "XTEST").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XTEST could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XTEST"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XTEST"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XTEST"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XTEST"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XTEST"] = make(map[int]xgb.NewErrorFun) +} + +const ( + CursorNone = 0 + CursorCurrent = 1 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CompareCursorCookie is a cookie used only for CompareCursor requests. +type CompareCursorCookie struct { + *xgb.Cookie +} + +// CompareCursor sends a checked request. +// If an error occurs, it will be returned with the reply by calling CompareCursorCookie.Reply() +func CompareCursor(c *xgb.Conn, Window xproto.Window, Cursor xproto.Cursor) CompareCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'CompareCursor' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(compareCursorRequest(c, Window, Cursor), cookie) + return CompareCursorCookie{cookie} +} + +// CompareCursorUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CompareCursorUnchecked(c *xgb.Conn, Window xproto.Window, Cursor xproto.Cursor) CompareCursorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'CompareCursor' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(compareCursorRequest(c, Window, Cursor), cookie) + return CompareCursorCookie{cookie} +} + +// CompareCursorReply represents the data returned from a CompareCursor request. +type CompareCursorReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Same bool +} + +// Reply blocks and returns the reply data for a CompareCursor request. +func (cook CompareCursorCookie) Reply() (*CompareCursorReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return compareCursorReply(buf), nil +} + +// compareCursorReply reads a byte slice into a CompareCursorReply value. +func compareCursorReply(buf []byte) *CompareCursorReply { + v := new(CompareCursorReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.Same = true + } else { + v.Same = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for CompareCursor +// compareCursorRequest writes a CompareCursor request to a byte slice. +func compareCursorRequest(c *xgb.Conn, Window xproto.Window, Cursor xproto.Cursor) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XTEST"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Cursor)) + b += 4 + + return buf +} + +// FakeInputCookie is a cookie used only for FakeInput requests. +type FakeInputCookie struct { + *xgb.Cookie +} + +// FakeInput sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FakeInput(c *xgb.Conn, Type byte, Detail byte, Time uint32, Root xproto.Window, RootX int16, RootY int16, Deviceid byte) FakeInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'FakeInput' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(fakeInputRequest(c, Type, Detail, Time, Root, RootX, RootY, Deviceid), cookie) + return FakeInputCookie{cookie} +} + +// FakeInputChecked sends a checked request. +// If an error occurs, it can be retrieved using FakeInputCookie.Check() +func FakeInputChecked(c *xgb.Conn, Type byte, Detail byte, Time uint32, Root xproto.Window, RootX int16, RootY int16, Deviceid byte) FakeInputCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'FakeInput' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(fakeInputRequest(c, Type, Detail, Time, Root, RootX, RootY, Deviceid), cookie) + return FakeInputCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FakeInputCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FakeInput +// fakeInputRequest writes a FakeInput request to a byte slice. +func fakeInputRequest(c *xgb.Conn, Type byte, Detail byte, Time uint32, Root xproto.Window, RootX int16, RootY int16, Deviceid byte) []byte { + size := 36 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XTEST"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = Type + b += 1 + + buf[b] = Detail + b += 1 + + b += 2 // padding + + xgb.Put32(buf[b:], Time) + b += 4 + + xgb.Put32(buf[b:], uint32(Root)) + b += 4 + + b += 8 // padding + + xgb.Put16(buf[b:], uint16(RootX)) + b += 2 + + xgb.Put16(buf[b:], uint16(RootY)) + b += 2 + + b += 7 // padding + + buf[b] = Deviceid + b += 1 + + return buf +} + +// GetVersionCookie is a cookie used only for GetVersion requests. +type GetVersionCookie struct { + *xgb.Cookie +} + +// GetVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetVersionCookie.Reply() +func GetVersion(c *xgb.Conn, MajorVersion byte, MinorVersion uint16) GetVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'GetVersion' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getVersionRequest(c, MajorVersion, MinorVersion), cookie) + return GetVersionCookie{cookie} +} + +// GetVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetVersionUnchecked(c *xgb.Conn, MajorVersion byte, MinorVersion uint16) GetVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'GetVersion' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getVersionRequest(c, MajorVersion, MinorVersion), cookie) + return GetVersionCookie{cookie} +} + +// GetVersionReply represents the data returned from a GetVersion request. +type GetVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + MajorVersion byte + MinorVersion uint16 +} + +// Reply blocks and returns the reply data for a GetVersion request. +func (cook GetVersionCookie) Reply() (*GetVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getVersionReply(buf), nil +} + +// getVersionReply reads a byte slice into a GetVersionReply value. +func getVersionReply(buf []byte) *GetVersionReply { + v := new(GetVersionReply) + b := 1 // skip reply determinant + + v.MajorVersion = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.MinorVersion = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for GetVersion +// getVersionRequest writes a GetVersion request to a byte slice. +func getVersionRequest(c *xgb.Conn, MajorVersion byte, MinorVersion uint16) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XTEST"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + buf[b] = MajorVersion + b += 1 + + b += 1 // padding + + xgb.Put16(buf[b:], MinorVersion) + b += 2 + + return buf +} + +// GrabControlCookie is a cookie used only for GrabControl requests. +type GrabControlCookie struct { + *xgb.Cookie +} + +// GrabControl sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabControl(c *xgb.Conn, Impervious bool) GrabControlCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'GrabControl' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(grabControlRequest(c, Impervious), cookie) + return GrabControlCookie{cookie} +} + +// GrabControlChecked sends a checked request. +// If an error occurs, it can be retrieved using GrabControlCookie.Check() +func GrabControlChecked(c *xgb.Conn, Impervious bool) GrabControlCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XTEST"]; !ok { + panic("Cannot issue request 'GrabControl' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(grabControlRequest(c, Impervious), cookie) + return GrabControlCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook GrabControlCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for GrabControl +// grabControlRequest writes a GrabControl request to a byte slice. +func grabControlRequest(c *xgb.Conn, Impervious bool) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XTEST"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + if Impervious { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} diff --git a/vend/xgb/xv/xv.go b/vend/xgb/xv/xv.go new file mode 100644 index 0000000..d4709a0 --- /dev/null +++ b/vend/xgb/xv/xv.go @@ -0,0 +1,3063 @@ +// Package xv is the X client API for the XVideo extension. +package xv + +// This file is automatically generated from xv.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/shm" + "github.com/jezek/xgb/xproto" +) + +// Init must be called before using the XVideo extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 6, "XVideo").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XVideo could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XVideo"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XVideo"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XVideo"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XVideo"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XVideo"] = make(map[int]xgb.NewErrorFun) +} + +type AdaptorInfo struct { + BaseId Port + NameSize uint16 + NumPorts uint16 + NumFormats uint16 + Type byte + // padding: 1 bytes + Name string // size: xgb.Pad((int(NameSize) * 1)) + // alignment gap to multiple of 4 + Formats []Format // size: xgb.Pad((int(NumFormats) * 8)) +} + +// AdaptorInfoRead reads a byte slice into a AdaptorInfo value. +func AdaptorInfoRead(buf []byte, v *AdaptorInfo) int { + b := 0 + + v.BaseId = Port(xgb.Get32(buf[b:])) + b += 4 + + v.NameSize = xgb.Get16(buf[b:]) + b += 2 + + v.NumPorts = xgb.Get16(buf[b:]) + b += 2 + + v.NumFormats = xgb.Get16(buf[b:]) + b += 2 + + v.Type = buf[b] + b += 1 + + b += 1 // padding + + { + byteString := make([]byte, v.NameSize) + copy(byteString[:v.NameSize], buf[b:]) + v.Name = string(byteString) + b += int(v.NameSize) + } + + b = (b + 3) & ^3 // alignment gap + + v.Formats = make([]Format, v.NumFormats) + b += FormatReadList(buf[b:], v.Formats) + + return b +} + +// AdaptorInfoReadList reads a byte slice into a list of AdaptorInfo values. +func AdaptorInfoReadList(buf []byte, dest []AdaptorInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = AdaptorInfo{} + b += AdaptorInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a AdaptorInfo value to a byte slice. +func (v AdaptorInfo) Bytes() []byte { + buf := make([]byte, (((12 + xgb.Pad((int(v.NameSize) * 1))) + 4) + xgb.Pad((int(v.NumFormats) * 8)))) + b := 0 + + xgb.Put32(buf[b:], uint32(v.BaseId)) + b += 4 + + xgb.Put16(buf[b:], v.NameSize) + b += 2 + + xgb.Put16(buf[b:], v.NumPorts) + b += 2 + + xgb.Put16(buf[b:], v.NumFormats) + b += 2 + + buf[b] = v.Type + b += 1 + + b += 1 // padding + + copy(buf[b:], v.Name[:v.NameSize]) + b += int(v.NameSize) + + b = (b + 3) & ^3 // alignment gap + + b += FormatListBytes(buf[b:], v.Formats) + + return buf[:b] +} + +// AdaptorInfoListBytes writes a list of AdaptorInfo values to a byte slice. +func AdaptorInfoListBytes(buf []byte, list []AdaptorInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// AdaptorInfoListSize computes the size (bytes) of a list of AdaptorInfo values. +func AdaptorInfoListSize(list []AdaptorInfo) int { + size := 0 + for _, item := range list { + size += (((12 + xgb.Pad((int(item.NameSize) * 1))) + 4) + xgb.Pad((int(item.NumFormats) * 8))) + } + return size +} + +const ( + AttributeFlagGettable = 1 + AttributeFlagSettable = 2 +) + +type AttributeInfo struct { + Flags uint32 + Min int32 + Max int32 + Size uint32 + Name string // size: xgb.Pad((int(Size) * 1)) + // alignment gap to multiple of 4 +} + +// AttributeInfoRead reads a byte slice into a AttributeInfo value. +func AttributeInfoRead(buf []byte, v *AttributeInfo) int { + b := 0 + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + v.Min = int32(xgb.Get32(buf[b:])) + b += 4 + + v.Max = int32(xgb.Get32(buf[b:])) + b += 4 + + v.Size = xgb.Get32(buf[b:]) + b += 4 + + { + byteString := make([]byte, v.Size) + copy(byteString[:v.Size], buf[b:]) + v.Name = string(byteString) + b += int(v.Size) + } + + b = (b + 3) & ^3 // alignment gap + + return b +} + +// AttributeInfoReadList reads a byte slice into a list of AttributeInfo values. +func AttributeInfoReadList(buf []byte, dest []AttributeInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = AttributeInfo{} + b += AttributeInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a AttributeInfo value to a byte slice. +func (v AttributeInfo) Bytes() []byte { + buf := make([]byte, ((16 + xgb.Pad((int(v.Size) * 1))) + 4)) + b := 0 + + xgb.Put32(buf[b:], v.Flags) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Min)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Max)) + b += 4 + + xgb.Put32(buf[b:], v.Size) + b += 4 + + copy(buf[b:], v.Name[:v.Size]) + b += int(v.Size) + + b = (b + 3) & ^3 // alignment gap + + return buf[:b] +} + +// AttributeInfoListBytes writes a list of AttributeInfo values to a byte slice. +func AttributeInfoListBytes(buf []byte, list []AttributeInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// AttributeInfoListSize computes the size (bytes) of a list of AttributeInfo values. +func AttributeInfoListSize(list []AttributeInfo) int { + size := 0 + for _, item := range list { + size += ((16 + xgb.Pad((int(item.Size) * 1))) + 4) + } + return size +} + +// BadBadControl is the error number for a BadBadControl. +const BadBadControl = 2 + +type BadControlError struct { + Sequence uint16 + NiceName string +} + +// BadControlErrorNew constructs a BadControlError value that implements xgb.Error from a byte slice. +func BadControlErrorNew(buf []byte) xgb.Error { + v := BadControlError{} + v.NiceName = "BadControl" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadControl error. +// This is mostly used internally. +func (err BadControlError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadControl error. If no bad value exists, 0 is returned. +func (err BadControlError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadControl error. + +func (err BadControlError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadControl {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XVideo"][2] = BadControlErrorNew +} + +// BadBadEncoding is the error number for a BadBadEncoding. +const BadBadEncoding = 1 + +type BadEncodingError struct { + Sequence uint16 + NiceName string +} + +// BadEncodingErrorNew constructs a BadEncodingError value that implements xgb.Error from a byte slice. +func BadEncodingErrorNew(buf []byte) xgb.Error { + v := BadEncodingError{} + v.NiceName = "BadEncoding" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadEncoding error. +// This is mostly used internally. +func (err BadEncodingError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadEncoding error. If no bad value exists, 0 is returned. +func (err BadEncodingError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadEncoding error. + +func (err BadEncodingError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadEncoding {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XVideo"][1] = BadEncodingErrorNew +} + +// BadBadPort is the error number for a BadBadPort. +const BadBadPort = 0 + +type BadPortError struct { + Sequence uint16 + NiceName string +} + +// BadPortErrorNew constructs a BadPortError value that implements xgb.Error from a byte slice. +func BadPortErrorNew(buf []byte) xgb.Error { + v := BadPortError{} + v.NiceName = "BadPort" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadBadPort error. +// This is mostly used internally. +func (err BadPortError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadBadPort error. If no bad value exists, 0 is returned. +func (err BadPortError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadBadPort error. + +func (err BadPortError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadBadPort {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["XVideo"][0] = BadPortErrorNew +} + +type Encoding uint32 + +func NewEncodingId(c *xgb.Conn) (Encoding, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Encoding(id), nil +} + +type EncodingInfo struct { + Encoding Encoding + NameSize uint16 + Width uint16 + Height uint16 + // padding: 2 bytes + Rate Rational + Name string // size: xgb.Pad((int(NameSize) * 1)) + // alignment gap to multiple of 4 +} + +// EncodingInfoRead reads a byte slice into a EncodingInfo value. +func EncodingInfoRead(buf []byte, v *EncodingInfo) int { + b := 0 + + v.Encoding = Encoding(xgb.Get32(buf[b:])) + b += 4 + + v.NameSize = xgb.Get16(buf[b:]) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Rate = Rational{} + b += RationalRead(buf[b:], &v.Rate) + + { + byteString := make([]byte, v.NameSize) + copy(byteString[:v.NameSize], buf[b:]) + v.Name = string(byteString) + b += int(v.NameSize) + } + + b = (b + 3) & ^3 // alignment gap + + return b +} + +// EncodingInfoReadList reads a byte slice into a list of EncodingInfo values. +func EncodingInfoReadList(buf []byte, dest []EncodingInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = EncodingInfo{} + b += EncodingInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a EncodingInfo value to a byte slice. +func (v EncodingInfo) Bytes() []byte { + buf := make([]byte, ((20 + xgb.Pad((int(v.NameSize) * 1))) + 4)) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Encoding)) + b += 4 + + xgb.Put16(buf[b:], v.NameSize) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + b += 2 // padding + + { + structBytes := v.Rate.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + copy(buf[b:], v.Name[:v.NameSize]) + b += int(v.NameSize) + + b = (b + 3) & ^3 // alignment gap + + return buf[:b] +} + +// EncodingInfoListBytes writes a list of EncodingInfo values to a byte slice. +func EncodingInfoListBytes(buf []byte, list []EncodingInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// EncodingInfoListSize computes the size (bytes) of a list of EncodingInfo values. +func EncodingInfoListSize(list []EncodingInfo) int { + size := 0 + for _, item := range list { + size += ((20 + xgb.Pad((int(item.NameSize) * 1))) + 4) + } + return size +} + +type Format struct { + Visual xproto.Visualid + Depth byte + // padding: 3 bytes +} + +// FormatRead reads a byte slice into a Format value. +func FormatRead(buf []byte, v *Format) int { + b := 0 + + v.Visual = xproto.Visualid(xgb.Get32(buf[b:])) + b += 4 + + v.Depth = buf[b] + b += 1 + + b += 3 // padding + + return b +} + +// FormatReadList reads a byte slice into a list of Format values. +func FormatReadList(buf []byte, dest []Format) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Format{} + b += FormatRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Format value to a byte slice. +func (v Format) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Visual)) + b += 4 + + buf[b] = v.Depth + b += 1 + + b += 3 // padding + + return buf[:b] +} + +// FormatListBytes writes a list of Format values to a byte slice. +func FormatListBytes(buf []byte, list []Format) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + GrabPortStatusSuccess = 0 + GrabPortStatusBadExtension = 1 + GrabPortStatusAlreadyGrabbed = 2 + GrabPortStatusInvalidTime = 3 + GrabPortStatusBadReply = 4 + GrabPortStatusBadAlloc = 5 +) + +type Image struct { + Id uint32 + Width uint16 + Height uint16 + DataSize uint32 + NumPlanes uint32 + Pitches []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) + Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) + Data []byte // size: xgb.Pad((int(DataSize) * 1)) +} + +// ImageRead reads a byte slice into a Image value. +func ImageRead(buf []byte, v *Image) int { + b := 0 + + v.Id = xgb.Get32(buf[b:]) + b += 4 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.DataSize = xgb.Get32(buf[b:]) + b += 4 + + v.NumPlanes = xgb.Get32(buf[b:]) + b += 4 + + v.Pitches = make([]uint32, v.NumPlanes) + for i := 0; i < int(v.NumPlanes); i++ { + v.Pitches[i] = xgb.Get32(buf[b:]) + b += 4 + } + + v.Offsets = make([]uint32, v.NumPlanes) + for i := 0; i < int(v.NumPlanes); i++ { + v.Offsets[i] = xgb.Get32(buf[b:]) + b += 4 + } + + v.Data = make([]byte, v.DataSize) + copy(v.Data[:v.DataSize], buf[b:]) + b += int(v.DataSize) + + return b +} + +// ImageReadList reads a byte slice into a list of Image values. +func ImageReadList(buf []byte, dest []Image) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Image{} + b += ImageRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Image value to a byte slice. +func (v Image) Bytes() []byte { + buf := make([]byte, (((16 + xgb.Pad((int(v.NumPlanes) * 4))) + xgb.Pad((int(v.NumPlanes) * 4))) + xgb.Pad((int(v.DataSize) * 1)))) + b := 0 + + xgb.Put32(buf[b:], v.Id) + b += 4 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put32(buf[b:], v.DataSize) + b += 4 + + xgb.Put32(buf[b:], v.NumPlanes) + b += 4 + + for i := 0; i < int(v.NumPlanes); i++ { + xgb.Put32(buf[b:], v.Pitches[i]) + b += 4 + } + + for i := 0; i < int(v.NumPlanes); i++ { + xgb.Put32(buf[b:], v.Offsets[i]) + b += 4 + } + + copy(buf[b:], v.Data[:v.DataSize]) + b += int(v.DataSize) + + return buf[:b] +} + +// ImageListBytes writes a list of Image values to a byte slice. +func ImageListBytes(buf []byte, list []Image) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ImageListSize computes the size (bytes) of a list of Image values. +func ImageListSize(list []Image) int { + size := 0 + for _, item := range list { + size += (((16 + xgb.Pad((int(item.NumPlanes) * 4))) + xgb.Pad((int(item.NumPlanes) * 4))) + xgb.Pad((int(item.DataSize) * 1))) + } + return size +} + +type ImageFormatInfo struct { + Id uint32 + Type byte + ByteOrder byte + // padding: 2 bytes + Guid []byte // size: 16 + Bpp byte + NumPlanes byte + // padding: 2 bytes + Depth byte + // padding: 3 bytes + RedMask uint32 + GreenMask uint32 + BlueMask uint32 + Format byte + // padding: 3 bytes + YSampleBits uint32 + USampleBits uint32 + VSampleBits uint32 + VhorzYPeriod uint32 + VhorzUPeriod uint32 + VhorzVPeriod uint32 + VvertYPeriod uint32 + VvertUPeriod uint32 + VvertVPeriod uint32 + VcompOrder []byte // size: 32 + VscanlineOrder byte + // padding: 11 bytes +} + +// ImageFormatInfoRead reads a byte slice into a ImageFormatInfo value. +func ImageFormatInfoRead(buf []byte, v *ImageFormatInfo) int { + b := 0 + + v.Id = xgb.Get32(buf[b:]) + b += 4 + + v.Type = buf[b] + b += 1 + + v.ByteOrder = buf[b] + b += 1 + + b += 2 // padding + + v.Guid = make([]byte, 16) + copy(v.Guid[:16], buf[b:]) + b += int(16) + + v.Bpp = buf[b] + b += 1 + + v.NumPlanes = buf[b] + b += 1 + + b += 2 // padding + + v.Depth = buf[b] + b += 1 + + b += 3 // padding + + v.RedMask = xgb.Get32(buf[b:]) + b += 4 + + v.GreenMask = xgb.Get32(buf[b:]) + b += 4 + + v.BlueMask = xgb.Get32(buf[b:]) + b += 4 + + v.Format = buf[b] + b += 1 + + b += 3 // padding + + v.YSampleBits = xgb.Get32(buf[b:]) + b += 4 + + v.USampleBits = xgb.Get32(buf[b:]) + b += 4 + + v.VSampleBits = xgb.Get32(buf[b:]) + b += 4 + + v.VhorzYPeriod = xgb.Get32(buf[b:]) + b += 4 + + v.VhorzUPeriod = xgb.Get32(buf[b:]) + b += 4 + + v.VhorzVPeriod = xgb.Get32(buf[b:]) + b += 4 + + v.VvertYPeriod = xgb.Get32(buf[b:]) + b += 4 + + v.VvertUPeriod = xgb.Get32(buf[b:]) + b += 4 + + v.VvertVPeriod = xgb.Get32(buf[b:]) + b += 4 + + v.VcompOrder = make([]byte, 32) + copy(v.VcompOrder[:32], buf[b:]) + b += int(32) + + v.VscanlineOrder = buf[b] + b += 1 + + b += 11 // padding + + return b +} + +// ImageFormatInfoReadList reads a byte slice into a list of ImageFormatInfo values. +func ImageFormatInfoReadList(buf []byte, dest []ImageFormatInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = ImageFormatInfo{} + b += ImageFormatInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a ImageFormatInfo value to a byte slice. +func (v ImageFormatInfo) Bytes() []byte { + buf := make([]byte, 128) + b := 0 + + xgb.Put32(buf[b:], v.Id) + b += 4 + + buf[b] = v.Type + b += 1 + + buf[b] = v.ByteOrder + b += 1 + + b += 2 // padding + + copy(buf[b:], v.Guid[:16]) + b += int(16) + + buf[b] = v.Bpp + b += 1 + + buf[b] = v.NumPlanes + b += 1 + + b += 2 // padding + + buf[b] = v.Depth + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], v.RedMask) + b += 4 + + xgb.Put32(buf[b:], v.GreenMask) + b += 4 + + xgb.Put32(buf[b:], v.BlueMask) + b += 4 + + buf[b] = v.Format + b += 1 + + b += 3 // padding + + xgb.Put32(buf[b:], v.YSampleBits) + b += 4 + + xgb.Put32(buf[b:], v.USampleBits) + b += 4 + + xgb.Put32(buf[b:], v.VSampleBits) + b += 4 + + xgb.Put32(buf[b:], v.VhorzYPeriod) + b += 4 + + xgb.Put32(buf[b:], v.VhorzUPeriod) + b += 4 + + xgb.Put32(buf[b:], v.VhorzVPeriod) + b += 4 + + xgb.Put32(buf[b:], v.VvertYPeriod) + b += 4 + + xgb.Put32(buf[b:], v.VvertUPeriod) + b += 4 + + xgb.Put32(buf[b:], v.VvertVPeriod) + b += 4 + + copy(buf[b:], v.VcompOrder[:32]) + b += int(32) + + buf[b] = v.VscanlineOrder + b += 1 + + b += 11 // padding + + return buf[:b] +} + +// ImageFormatInfoListBytes writes a list of ImageFormatInfo values to a byte slice. +func ImageFormatInfoListBytes(buf []byte, list []ImageFormatInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// ImageFormatInfoListSize computes the size (bytes) of a list of ImageFormatInfo values. +func ImageFormatInfoListSize(list []ImageFormatInfo) int { + size := 0 + for _ = range list { + size += 128 + } + return size +} + +const ( + ImageFormatInfoFormatPacked = 0 + ImageFormatInfoFormatPlanar = 1 +) + +const ( + ImageFormatInfoTypeRgb = 0 + ImageFormatInfoTypeYuv = 1 +) + +type Port uint32 + +func NewPortId(c *xgb.Conn) (Port, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Port(id), nil +} + +// PortNotify is the event number for a PortNotifyEvent. +const PortNotify = 1 + +type PortNotifyEvent struct { + Sequence uint16 + // padding: 1 bytes + Time xproto.Timestamp + Port Port + Attribute xproto.Atom + Value int32 +} + +// PortNotifyEventNew constructs a PortNotifyEvent value that implements xgb.Event from a byte slice. +func PortNotifyEventNew(buf []byte) xgb.Event { + v := PortNotifyEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Port = Port(xgb.Get32(buf[b:])) + b += 4 + + v.Attribute = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + v.Value = int32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a PortNotifyEvent value to a byte slice. +func (v PortNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 1 + b += 1 + + b += 1 // padding + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Attribute)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Value)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the PortNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v PortNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of PortNotifyEvent. +func (v PortNotifyEvent) String() string { + fieldVals := make([]string, 0, 5) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Port: %d", v.Port)) + fieldVals = append(fieldVals, xgb.Sprintf("Attribute: %d", v.Attribute)) + fieldVals = append(fieldVals, xgb.Sprintf("Value: %d", v.Value)) + return "PortNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["XVideo"][1] = PortNotifyEventNew +} + +type Rational struct { + Numerator int32 + Denominator int32 +} + +// RationalRead reads a byte slice into a Rational value. +func RationalRead(buf []byte, v *Rational) int { + b := 0 + + v.Numerator = int32(xgb.Get32(buf[b:])) + b += 4 + + v.Denominator = int32(xgb.Get32(buf[b:])) + b += 4 + + return b +} + +// RationalReadList reads a byte slice into a list of Rational values. +func RationalReadList(buf []byte, dest []Rational) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = Rational{} + b += RationalRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a Rational value to a byte slice. +func (v Rational) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Numerator)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Denominator)) + b += 4 + + return buf[:b] +} + +// RationalListBytes writes a list of Rational values to a byte slice. +func RationalListBytes(buf []byte, list []Rational) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +const ( + ScanlineOrderTopToBottom = 0 + ScanlineOrderBottomToTop = 1 +) + +const ( + TypeInputMask = 1 + TypeOutputMask = 2 + TypeVideoMask = 4 + TypeStillMask = 8 + TypeImageMask = 16 +) + +// VideoNotify is the event number for a VideoNotifyEvent. +const VideoNotify = 0 + +type VideoNotifyEvent struct { + Sequence uint16 + Reason byte + Time xproto.Timestamp + Drawable xproto.Drawable + Port Port +} + +// VideoNotifyEventNew constructs a VideoNotifyEvent value that implements xgb.Event from a byte slice. +func VideoNotifyEventNew(buf []byte) xgb.Event { + v := VideoNotifyEvent{} + b := 1 // don't read event number + + v.Reason = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Time = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Drawable = xproto.Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.Port = Port(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Bytes writes a VideoNotifyEvent value to a byte slice. +func (v VideoNotifyEvent) Bytes() []byte { + buf := make([]byte, 32) + b := 0 + + // write event number + buf[b] = 0 + b += 1 + + buf[b] = v.Reason + b += 1 + + b += 2 // skip sequence number + + xgb.Put32(buf[b:], uint32(v.Time)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Port)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the VideoNotify event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v VideoNotifyEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of VideoNotifyEvent. +func (v VideoNotifyEvent) String() string { + fieldVals := make([]string, 0, 4) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Reason: %d", v.Reason)) + fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("Port: %d", v.Port)) + return "VideoNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["XVideo"][0] = VideoNotifyEventNew +} + +const ( + VideoNotifyReasonStarted = 0 + VideoNotifyReasonStopped = 1 + VideoNotifyReasonBusy = 2 + VideoNotifyReasonPreempted = 3 + VideoNotifyReasonHardError = 4 +) + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// GetPortAttributeCookie is a cookie used only for GetPortAttribute requests. +type GetPortAttributeCookie struct { + *xgb.Cookie +} + +// GetPortAttribute sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetPortAttributeCookie.Reply() +func GetPortAttribute(c *xgb.Conn, Port Port, Attribute xproto.Atom) GetPortAttributeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getPortAttributeRequest(c, Port, Attribute), cookie) + return GetPortAttributeCookie{cookie} +} + +// GetPortAttributeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetPortAttributeUnchecked(c *xgb.Conn, Port Port, Attribute xproto.Atom) GetPortAttributeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getPortAttributeRequest(c, Port, Attribute), cookie) + return GetPortAttributeCookie{cookie} +} + +// GetPortAttributeReply represents the data returned from a GetPortAttribute request. +type GetPortAttributeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Value int32 +} + +// Reply blocks and returns the reply data for a GetPortAttribute request. +func (cook GetPortAttributeCookie) Reply() (*GetPortAttributeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getPortAttributeReply(buf), nil +} + +// getPortAttributeReply reads a byte slice into a GetPortAttributeReply value. +func getPortAttributeReply(buf []byte) *GetPortAttributeReply { + v := new(GetPortAttributeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Value = int32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for GetPortAttribute +// getPortAttributeRequest writes a GetPortAttribute request to a byte slice. +func getPortAttributeRequest(c *xgb.Conn, Port Port, Attribute xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 14 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Attribute)) + b += 4 + + return buf +} + +// GetStillCookie is a cookie used only for GetStill requests. +type GetStillCookie struct { + *xgb.Cookie +} + +// GetStill sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetStill(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetStillCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GetStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(getStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return GetStillCookie{cookie} +} + +// GetStillChecked sends a checked request. +// If an error occurs, it can be retrieved using GetStillCookie.Check() +func GetStillChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetStillCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GetStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(getStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return GetStillCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook GetStillCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for GetStill +// getStillRequest writes a GetStill request to a byte slice. +func getStillRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(VidX)) + b += 2 + + xgb.Put16(buf[b:], uint16(VidY)) + b += 2 + + xgb.Put16(buf[b:], VidW) + b += 2 + + xgb.Put16(buf[b:], VidH) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwY)) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + return buf +} + +// GetVideoCookie is a cookie used only for GetVideo requests. +type GetVideoCookie struct { + *xgb.Cookie +} + +// GetVideo sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetVideo(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetVideoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GetVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(getVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return GetVideoCookie{cookie} +} + +// GetVideoChecked sends a checked request. +// If an error occurs, it can be retrieved using GetVideoCookie.Check() +func GetVideoChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetVideoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GetVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(getVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return GetVideoCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook GetVideoCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for GetVideo +// getVideoRequest writes a GetVideo request to a byte slice. +func getVideoRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(VidX)) + b += 2 + + xgb.Put16(buf[b:], uint16(VidY)) + b += 2 + + xgb.Put16(buf[b:], VidW) + b += 2 + + xgb.Put16(buf[b:], VidH) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwY)) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + return buf +} + +// GrabPortCookie is a cookie used only for GrabPort requests. +type GrabPortCookie struct { + *xgb.Cookie +} + +// GrabPort sends a checked request. +// If an error occurs, it will be returned with the reply by calling GrabPortCookie.Reply() +func GrabPort(c *xgb.Conn, Port Port, Time xproto.Timestamp) GrabPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(grabPortRequest(c, Port, Time), cookie) + return GrabPortCookie{cookie} +} + +// GrabPortUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GrabPortUnchecked(c *xgb.Conn, Port Port, Time xproto.Timestamp) GrabPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'GrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(grabPortRequest(c, Port, Time), cookie) + return GrabPortCookie{cookie} +} + +// GrabPortReply represents the data returned from a GrabPort request. +type GrabPortReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Result byte +} + +// Reply blocks and returns the reply data for a GrabPort request. +func (cook GrabPortCookie) Reply() (*GrabPortReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return grabPortReply(buf), nil +} + +// grabPortReply reads a byte slice into a GrabPortReply value. +func grabPortReply(buf []byte) *GrabPortReply { + v := new(GrabPortReply) + b := 1 // skip reply determinant + + v.Result = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + return v +} + +// Write request to wire for GrabPort +// grabPortRequest writes a GrabPort request to a byte slice. +func grabPortRequest(c *xgb.Conn, Port Port, Time xproto.Timestamp) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} + +// ListImageFormatsCookie is a cookie used only for ListImageFormats requests. +type ListImageFormatsCookie struct { + *xgb.Cookie +} + +// ListImageFormats sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListImageFormatsCookie.Reply() +func ListImageFormats(c *xgb.Conn, Port Port) ListImageFormatsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'ListImageFormats' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listImageFormatsRequest(c, Port), cookie) + return ListImageFormatsCookie{cookie} +} + +// ListImageFormatsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListImageFormatsUnchecked(c *xgb.Conn, Port Port) ListImageFormatsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'ListImageFormats' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listImageFormatsRequest(c, Port), cookie) + return ListImageFormatsCookie{cookie} +} + +// ListImageFormatsReply represents the data returned from a ListImageFormats request. +type ListImageFormatsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumFormats uint32 + // padding: 20 bytes + Format []ImageFormatInfo // size: ImageFormatInfoListSize(Format) +} + +// Reply blocks and returns the reply data for a ListImageFormats request. +func (cook ListImageFormatsCookie) Reply() (*ListImageFormatsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listImageFormatsReply(buf), nil +} + +// listImageFormatsReply reads a byte slice into a ListImageFormatsReply value. +func listImageFormatsReply(buf []byte) *ListImageFormatsReply { + v := new(ListImageFormatsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumFormats = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Format = make([]ImageFormatInfo, v.NumFormats) + b += ImageFormatInfoReadList(buf[b:], v.Format) + + return v +} + +// Write request to wire for ListImageFormats +// listImageFormatsRequest writes a ListImageFormats request to a byte slice. +func listImageFormatsRequest(c *xgb.Conn, Port Port) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 16 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + return buf +} + +// PutImageCookie is a cookie used only for PutImage requests. +type PutImageCookie struct { + *xgb.Cookie +} + +// PutImage sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PutImage(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Id uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, Data []byte) PutImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'PutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(putImageRequest(c, Port, Drawable, Gc, Id, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, Data), cookie) + return PutImageCookie{cookie} +} + +// PutImageChecked sends a checked request. +// If an error occurs, it can be retrieved using PutImageCookie.Check() +func PutImageChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Id uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, Data []byte) PutImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'PutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(putImageRequest(c, Port, Drawable, Gc, Id, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, Data), cookie) + return PutImageCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PutImageCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PutImage +// putImageRequest writes a PutImage request to a byte slice. +func putImageRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Id uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, Data []byte) []byte { + size := xgb.Pad((40 + xgb.Pad((len(Data) * 1)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 18 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put32(buf[b:], Id) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + xgb.Put16(buf[b:], SrcW) + b += 2 + + xgb.Put16(buf[b:], SrcH) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwY)) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + copy(buf[b:], Data[:len(Data)]) + b += int(len(Data)) + + return buf +} + +// PutStillCookie is a cookie used only for PutStill requests. +type PutStillCookie struct { + *xgb.Cookie +} + +// PutStill sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PutStill(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutStillCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'PutStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(putStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return PutStillCookie{cookie} +} + +// PutStillChecked sends a checked request. +// If an error occurs, it can be retrieved using PutStillCookie.Check() +func PutStillChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutStillCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'PutStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(putStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return PutStillCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PutStillCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PutStill +// putStillRequest writes a PutStill request to a byte slice. +func putStillRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(VidX)) + b += 2 + + xgb.Put16(buf[b:], uint16(VidY)) + b += 2 + + xgb.Put16(buf[b:], VidW) + b += 2 + + xgb.Put16(buf[b:], VidH) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwY)) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + return buf +} + +// PutVideoCookie is a cookie used only for PutVideo requests. +type PutVideoCookie struct { + *xgb.Cookie +} + +// PutVideo sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func PutVideo(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutVideoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'PutVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(putVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return PutVideoCookie{cookie} +} + +// PutVideoChecked sends a checked request. +// If an error occurs, it can be retrieved using PutVideoCookie.Check() +func PutVideoChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutVideoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'PutVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(putVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie) + return PutVideoCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook PutVideoCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for PutVideo +// putVideoRequest writes a PutVideo request to a byte slice. +func putVideoRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put16(buf[b:], uint16(VidX)) + b += 2 + + xgb.Put16(buf[b:], uint16(VidY)) + b += 2 + + xgb.Put16(buf[b:], VidW) + b += 2 + + xgb.Put16(buf[b:], VidH) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwY)) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + return buf +} + +// QueryAdaptorsCookie is a cookie used only for QueryAdaptors requests. +type QueryAdaptorsCookie struct { + *xgb.Cookie +} + +// QueryAdaptors sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryAdaptorsCookie.Reply() +func QueryAdaptors(c *xgb.Conn, Window xproto.Window) QueryAdaptorsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryAdaptors' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryAdaptorsRequest(c, Window), cookie) + return QueryAdaptorsCookie{cookie} +} + +// QueryAdaptorsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryAdaptorsUnchecked(c *xgb.Conn, Window xproto.Window) QueryAdaptorsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryAdaptors' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryAdaptorsRequest(c, Window), cookie) + return QueryAdaptorsCookie{cookie} +} + +// QueryAdaptorsReply represents the data returned from a QueryAdaptors request. +type QueryAdaptorsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAdaptors uint16 + // padding: 22 bytes + Info []AdaptorInfo // size: AdaptorInfoListSize(Info) +} + +// Reply blocks and returns the reply data for a QueryAdaptors request. +func (cook QueryAdaptorsCookie) Reply() (*QueryAdaptorsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryAdaptorsReply(buf), nil +} + +// queryAdaptorsReply reads a byte slice into a QueryAdaptorsReply value. +func queryAdaptorsReply(buf []byte) *QueryAdaptorsReply { + v := new(QueryAdaptorsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAdaptors = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Info = make([]AdaptorInfo, v.NumAdaptors) + b += AdaptorInfoReadList(buf[b:], v.Info) + + return v +} + +// Write request to wire for QueryAdaptors +// queryAdaptorsRequest writes a QueryAdaptors request to a byte slice. +func queryAdaptorsRequest(c *xgb.Conn, Window xproto.Window) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + return buf +} + +// QueryBestSizeCookie is a cookie used only for QueryBestSize requests. +type QueryBestSizeCookie struct { + *xgb.Cookie +} + +// QueryBestSize sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryBestSizeCookie.Reply() +func QueryBestSize(c *xgb.Conn, Port Port, VidW uint16, VidH uint16, DrwW uint16, DrwH uint16, Motion bool) QueryBestSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryBestSize' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryBestSizeRequest(c, Port, VidW, VidH, DrwW, DrwH, Motion), cookie) + return QueryBestSizeCookie{cookie} +} + +// QueryBestSizeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryBestSizeUnchecked(c *xgb.Conn, Port Port, VidW uint16, VidH uint16, DrwW uint16, DrwH uint16, Motion bool) QueryBestSizeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryBestSize' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryBestSizeRequest(c, Port, VidW, VidH, DrwW, DrwH, Motion), cookie) + return QueryBestSizeCookie{cookie} +} + +// QueryBestSizeReply represents the data returned from a QueryBestSize request. +type QueryBestSizeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + ActualWidth uint16 + ActualHeight uint16 +} + +// Reply blocks and returns the reply data for a QueryBestSize request. +func (cook QueryBestSizeCookie) Reply() (*QueryBestSizeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryBestSizeReply(buf), nil +} + +// queryBestSizeReply reads a byte slice into a QueryBestSizeReply value. +func queryBestSizeReply(buf []byte) *QueryBestSizeReply { + v := new(QueryBestSizeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ActualWidth = xgb.Get16(buf[b:]) + b += 2 + + v.ActualHeight = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryBestSize +// queryBestSizeRequest writes a QueryBestSize request to a byte slice. +func queryBestSizeRequest(c *xgb.Conn, Port Port, VidW uint16, VidH uint16, DrwW uint16, DrwH uint16, Motion bool) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 12 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put16(buf[b:], VidW) + b += 2 + + xgb.Put16(buf[b:], VidH) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + if Motion { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// QueryEncodingsCookie is a cookie used only for QueryEncodings requests. +type QueryEncodingsCookie struct { + *xgb.Cookie +} + +// QueryEncodings sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryEncodingsCookie.Reply() +func QueryEncodings(c *xgb.Conn, Port Port) QueryEncodingsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryEncodings' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryEncodingsRequest(c, Port), cookie) + return QueryEncodingsCookie{cookie} +} + +// QueryEncodingsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryEncodingsUnchecked(c *xgb.Conn, Port Port) QueryEncodingsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryEncodings' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryEncodingsRequest(c, Port), cookie) + return QueryEncodingsCookie{cookie} +} + +// QueryEncodingsReply represents the data returned from a QueryEncodings request. +type QueryEncodingsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumEncodings uint16 + // padding: 22 bytes + Info []EncodingInfo // size: EncodingInfoListSize(Info) +} + +// Reply blocks and returns the reply data for a QueryEncodings request. +func (cook QueryEncodingsCookie) Reply() (*QueryEncodingsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryEncodingsReply(buf), nil +} + +// queryEncodingsReply reads a byte slice into a QueryEncodingsReply value. +func queryEncodingsReply(buf []byte) *QueryEncodingsReply { + v := new(QueryEncodingsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumEncodings = xgb.Get16(buf[b:]) + b += 2 + + b += 22 // padding + + v.Info = make([]EncodingInfo, v.NumEncodings) + b += EncodingInfoReadList(buf[b:], v.Info) + + return v +} + +// Write request to wire for QueryEncodings +// queryEncodingsRequest writes a QueryEncodings request to a byte slice. +func queryEncodingsRequest(c *xgb.Conn, Port Port) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + return buf +} + +// QueryExtensionCookie is a cookie used only for QueryExtension requests. +type QueryExtensionCookie struct { + *xgb.Cookie +} + +// QueryExtension sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryExtensionCookie.Reply() +func QueryExtension(c *xgb.Conn) QueryExtensionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryExtension' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryExtensionRequest(c), cookie) + return QueryExtensionCookie{cookie} +} + +// QueryExtensionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryExtensionUnchecked(c *xgb.Conn) QueryExtensionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryExtension' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryExtensionRequest(c), cookie) + return QueryExtensionCookie{cookie} +} + +// QueryExtensionReply represents the data returned from a QueryExtension request. +type QueryExtensionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Major uint16 + Minor uint16 +} + +// Reply blocks and returns the reply data for a QueryExtension request. +func (cook QueryExtensionCookie) Reply() (*QueryExtensionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryExtensionReply(buf), nil +} + +// queryExtensionReply reads a byte slice into a QueryExtensionReply value. +func queryExtensionReply(buf []byte) *QueryExtensionReply { + v := new(QueryExtensionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Major = xgb.Get16(buf[b:]) + b += 2 + + v.Minor = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// Write request to wire for QueryExtension +// queryExtensionRequest writes a QueryExtension request to a byte slice. +func queryExtensionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + +// QueryImageAttributesCookie is a cookie used only for QueryImageAttributes requests. +type QueryImageAttributesCookie struct { + *xgb.Cookie +} + +// QueryImageAttributes sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryImageAttributesCookie.Reply() +func QueryImageAttributes(c *xgb.Conn, Port Port, Id uint32, Width uint16, Height uint16) QueryImageAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryImageAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryImageAttributesRequest(c, Port, Id, Width, Height), cookie) + return QueryImageAttributesCookie{cookie} +} + +// QueryImageAttributesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryImageAttributesUnchecked(c *xgb.Conn, Port Port, Id uint32, Width uint16, Height uint16) QueryImageAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryImageAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryImageAttributesRequest(c, Port, Id, Width, Height), cookie) + return QueryImageAttributesCookie{cookie} +} + +// QueryImageAttributesReply represents the data returned from a QueryImageAttributes request. +type QueryImageAttributesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumPlanes uint32 + DataSize uint32 + Width uint16 + Height uint16 + // padding: 12 bytes + Pitches []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) + Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) +} + +// Reply blocks and returns the reply data for a QueryImageAttributes request. +func (cook QueryImageAttributesCookie) Reply() (*QueryImageAttributesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryImageAttributesReply(buf), nil +} + +// queryImageAttributesReply reads a byte slice into a QueryImageAttributesReply value. +func queryImageAttributesReply(buf []byte) *QueryImageAttributesReply { + v := new(QueryImageAttributesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumPlanes = xgb.Get32(buf[b:]) + b += 4 + + v.DataSize = xgb.Get32(buf[b:]) + b += 4 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + b += 12 // padding + + v.Pitches = make([]uint32, v.NumPlanes) + for i := 0; i < int(v.NumPlanes); i++ { + v.Pitches[i] = xgb.Get32(buf[b:]) + b += 4 + } + + v.Offsets = make([]uint32, v.NumPlanes) + for i := 0; i < int(v.NumPlanes); i++ { + v.Offsets[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for QueryImageAttributes +// queryImageAttributesRequest writes a QueryImageAttributes request to a byte slice. +func queryImageAttributesRequest(c *xgb.Conn, Port Port, Id uint32, Width uint16, Height uint16) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 17 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], Id) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// QueryPortAttributesCookie is a cookie used only for QueryPortAttributes requests. +type QueryPortAttributesCookie struct { + *xgb.Cookie +} + +// QueryPortAttributes sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryPortAttributesCookie.Reply() +func QueryPortAttributes(c *xgb.Conn, Port Port) QueryPortAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryPortAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryPortAttributesRequest(c, Port), cookie) + return QueryPortAttributesCookie{cookie} +} + +// QueryPortAttributesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryPortAttributesUnchecked(c *xgb.Conn, Port Port) QueryPortAttributesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'QueryPortAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryPortAttributesRequest(c, Port), cookie) + return QueryPortAttributesCookie{cookie} +} + +// QueryPortAttributesReply represents the data returned from a QueryPortAttributes request. +type QueryPortAttributesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + NumAttributes uint32 + TextSize uint32 + // padding: 16 bytes + Attributes []AttributeInfo // size: AttributeInfoListSize(Attributes) +} + +// Reply blocks and returns the reply data for a QueryPortAttributes request. +func (cook QueryPortAttributesCookie) Reply() (*QueryPortAttributesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryPortAttributesReply(buf), nil +} + +// queryPortAttributesReply reads a byte slice into a QueryPortAttributesReply value. +func queryPortAttributesReply(buf []byte) *QueryPortAttributesReply { + v := new(QueryPortAttributesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.NumAttributes = xgb.Get32(buf[b:]) + b += 4 + + v.TextSize = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + v.Attributes = make([]AttributeInfo, v.NumAttributes) + b += AttributeInfoReadList(buf[b:], v.Attributes) + + return v +} + +// Write request to wire for QueryPortAttributes +// queryPortAttributesRequest writes a QueryPortAttributes request to a byte slice. +func queryPortAttributesRequest(c *xgb.Conn, Port Port) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 15 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + return buf +} + +// SelectPortNotifyCookie is a cookie used only for SelectPortNotify requests. +type SelectPortNotifyCookie struct { + *xgb.Cookie +} + +// SelectPortNotify sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectPortNotify(c *xgb.Conn, Port Port, Onoff bool) SelectPortNotifyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'SelectPortNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectPortNotifyRequest(c, Port, Onoff), cookie) + return SelectPortNotifyCookie{cookie} +} + +// SelectPortNotifyChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectPortNotifyCookie.Check() +func SelectPortNotifyChecked(c *xgb.Conn, Port Port, Onoff bool) SelectPortNotifyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'SelectPortNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectPortNotifyRequest(c, Port, Onoff), cookie) + return SelectPortNotifyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectPortNotifyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectPortNotify +// selectPortNotifyRequest writes a SelectPortNotify request to a byte slice. +func selectPortNotifyRequest(c *xgb.Conn, Port Port, Onoff bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 11 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + if Onoff { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// SelectVideoNotifyCookie is a cookie used only for SelectVideoNotify requests. +type SelectVideoNotifyCookie struct { + *xgb.Cookie +} + +// SelectVideoNotify sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SelectVideoNotify(c *xgb.Conn, Drawable xproto.Drawable, Onoff bool) SelectVideoNotifyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'SelectVideoNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(selectVideoNotifyRequest(c, Drawable, Onoff), cookie) + return SelectVideoNotifyCookie{cookie} +} + +// SelectVideoNotifyChecked sends a checked request. +// If an error occurs, it can be retrieved using SelectVideoNotifyCookie.Check() +func SelectVideoNotifyChecked(c *xgb.Conn, Drawable xproto.Drawable, Onoff bool) SelectVideoNotifyCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'SelectVideoNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(selectVideoNotifyRequest(c, Drawable, Onoff), cookie) + return SelectVideoNotifyCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SelectVideoNotifyCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SelectVideoNotify +// selectVideoNotifyRequest writes a SelectVideoNotify request to a byte slice. +func selectVideoNotifyRequest(c *xgb.Conn, Drawable xproto.Drawable, Onoff bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 10 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + if Onoff { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + b += 3 // padding + + return buf +} + +// SetPortAttributeCookie is a cookie used only for SetPortAttribute requests. +type SetPortAttributeCookie struct { + *xgb.Cookie +} + +// SetPortAttribute sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetPortAttribute(c *xgb.Conn, Port Port, Attribute xproto.Atom, Value int32) SetPortAttributeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'SetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setPortAttributeRequest(c, Port, Attribute, Value), cookie) + return SetPortAttributeCookie{cookie} +} + +// SetPortAttributeChecked sends a checked request. +// If an error occurs, it can be retrieved using SetPortAttributeCookie.Check() +func SetPortAttributeChecked(c *xgb.Conn, Port Port, Attribute xproto.Atom, Value int32) SetPortAttributeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'SetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setPortAttributeRequest(c, Port, Attribute, Value), cookie) + return SetPortAttributeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetPortAttributeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetPortAttribute +// setPortAttributeRequest writes a SetPortAttribute request to a byte slice. +func setPortAttributeRequest(c *xgb.Conn, Port Port, Attribute xproto.Atom, Value int32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 13 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Attribute)) + b += 4 + + xgb.Put32(buf[b:], uint32(Value)) + b += 4 + + return buf +} + +// ShmPutImageCookie is a cookie used only for ShmPutImage requests. +type ShmPutImageCookie struct { + *xgb.Cookie +} + +// ShmPutImage sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ShmPutImage(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Shmseg shm.Seg, Id uint32, Offset uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, SendEvent byte) ShmPutImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'ShmPutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(shmPutImageRequest(c, Port, Drawable, Gc, Shmseg, Id, Offset, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, SendEvent), cookie) + return ShmPutImageCookie{cookie} +} + +// ShmPutImageChecked sends a checked request. +// If an error occurs, it can be retrieved using ShmPutImageCookie.Check() +func ShmPutImageChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Shmseg shm.Seg, Id uint32, Offset uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, SendEvent byte) ShmPutImageCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'ShmPutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(shmPutImageRequest(c, Port, Drawable, Gc, Shmseg, Id, Offset, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, SendEvent), cookie) + return ShmPutImageCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook ShmPutImageCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for ShmPutImage +// shmPutImageRequest writes a ShmPutImage request to a byte slice. +func shmPutImageRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Shmseg shm.Seg, Id uint32, Offset uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, SendEvent byte) []byte { + size := 52 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 19 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + xgb.Put32(buf[b:], uint32(Gc)) + b += 4 + + xgb.Put32(buf[b:], uint32(Shmseg)) + b += 4 + + xgb.Put32(buf[b:], Id) + b += 4 + + xgb.Put32(buf[b:], Offset) + b += 4 + + xgb.Put16(buf[b:], uint16(SrcX)) + b += 2 + + xgb.Put16(buf[b:], uint16(SrcY)) + b += 2 + + xgb.Put16(buf[b:], SrcW) + b += 2 + + xgb.Put16(buf[b:], SrcH) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwX)) + b += 2 + + xgb.Put16(buf[b:], uint16(DrwY)) + b += 2 + + xgb.Put16(buf[b:], DrwW) + b += 2 + + xgb.Put16(buf[b:], DrwH) + b += 2 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + buf[b] = SendEvent + b += 1 + + b += 3 // padding + + return buf +} + +// StopVideoCookie is a cookie used only for StopVideo requests. +type StopVideoCookie struct { + *xgb.Cookie +} + +// StopVideo sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func StopVideo(c *xgb.Conn, Port Port, Drawable xproto.Drawable) StopVideoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'StopVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(stopVideoRequest(c, Port, Drawable), cookie) + return StopVideoCookie{cookie} +} + +// StopVideoChecked sends a checked request. +// If an error occurs, it can be retrieved using StopVideoCookie.Check() +func StopVideoChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable) StopVideoCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'StopVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(stopVideoRequest(c, Port, Drawable), cookie) + return StopVideoCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook StopVideoCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for StopVideo +// stopVideoRequest writes a StopVideo request to a byte slice. +func stopVideoRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 9 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Drawable)) + b += 4 + + return buf +} + +// UngrabPortCookie is a cookie used only for UngrabPort requests. +type UngrabPortCookie struct { + *xgb.Cookie +} + +// UngrabPort sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func UngrabPort(c *xgb.Conn, Port Port, Time xproto.Timestamp) UngrabPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'UngrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(ungrabPortRequest(c, Port, Time), cookie) + return UngrabPortCookie{cookie} +} + +// UngrabPortChecked sends a checked request. +// If an error occurs, it can be retrieved using UngrabPortCookie.Check() +func UngrabPortChecked(c *xgb.Conn, Port Port, Time xproto.Timestamp) UngrabPortCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo"]; !ok { + panic("Cannot issue request 'UngrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(ungrabPortRequest(c, Port, Time), cookie) + return UngrabPortCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook UngrabPortCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for UngrabPort +// ungrabPortRequest writes a UngrabPort request to a byte slice. +func ungrabPortRequest(c *xgb.Conn, Port Port, Time xproto.Timestamp) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Port)) + b += 4 + + xgb.Put32(buf[b:], uint32(Time)) + b += 4 + + return buf +} diff --git a/vend/xgb/xvmc/xvmc.go b/vend/xgb/xvmc/xvmc.go new file mode 100644 index 0000000..3f61416 --- /dev/null +++ b/vend/xgb/xvmc/xvmc.go @@ -0,0 +1,1041 @@ +// Package xvmc is the X client API for the XVideo-MotionCompensation extension. +package xvmc + +// This file is automatically generated from xvmc.xml. Edit at your peril! + +import ( + "github.com/jezek/xgb" + + "github.com/jezek/xgb/xproto" + "github.com/jezek/xgb/xv" +) + +// Init must be called before using the XVideo-MotionCompensation extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 25, "XVideo-MotionCompensation").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named XVideo-MotionCompensation could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["XVideo-MotionCompensation"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["XVideo-MotionCompensation"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["XVideo-MotionCompensation"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["XVideo-MotionCompensation"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["XVideo-MotionCompensation"] = make(map[int]xgb.NewErrorFun) +} + +type Context uint32 + +func NewContextId(c *xgb.Conn) (Context, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Context(id), nil +} + +type Subpicture uint32 + +func NewSubpictureId(c *xgb.Conn) (Subpicture, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Subpicture(id), nil +} + +type Surface uint32 + +func NewSurfaceId(c *xgb.Conn) (Surface, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Surface(id), nil +} + +type SurfaceInfo struct { + Id Surface + ChromaFormat uint16 + Pad0 uint16 + MaxWidth uint16 + MaxHeight uint16 + SubpictureMaxWidth uint16 + SubpictureMaxHeight uint16 + McType uint32 + Flags uint32 +} + +// SurfaceInfoRead reads a byte slice into a SurfaceInfo value. +func SurfaceInfoRead(buf []byte, v *SurfaceInfo) int { + b := 0 + + v.Id = Surface(xgb.Get32(buf[b:])) + b += 4 + + v.ChromaFormat = xgb.Get16(buf[b:]) + b += 2 + + v.Pad0 = xgb.Get16(buf[b:]) + b += 2 + + v.MaxWidth = xgb.Get16(buf[b:]) + b += 2 + + v.MaxHeight = xgb.Get16(buf[b:]) + b += 2 + + v.SubpictureMaxWidth = xgb.Get16(buf[b:]) + b += 2 + + v.SubpictureMaxHeight = xgb.Get16(buf[b:]) + b += 2 + + v.McType = xgb.Get32(buf[b:]) + b += 4 + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// SurfaceInfoReadList reads a byte slice into a list of SurfaceInfo values. +func SurfaceInfoReadList(buf []byte, dest []SurfaceInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = SurfaceInfo{} + b += SurfaceInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a SurfaceInfo value to a byte slice. +func (v SurfaceInfo) Bytes() []byte { + buf := make([]byte, 24) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Id)) + b += 4 + + xgb.Put16(buf[b:], v.ChromaFormat) + b += 2 + + xgb.Put16(buf[b:], v.Pad0) + b += 2 + + xgb.Put16(buf[b:], v.MaxWidth) + b += 2 + + xgb.Put16(buf[b:], v.MaxHeight) + b += 2 + + xgb.Put16(buf[b:], v.SubpictureMaxWidth) + b += 2 + + xgb.Put16(buf[b:], v.SubpictureMaxHeight) + b += 2 + + xgb.Put32(buf[b:], v.McType) + b += 4 + + xgb.Put32(buf[b:], v.Flags) + b += 4 + + return buf[:b] +} + +// SurfaceInfoListBytes writes a list of SurfaceInfo values to a byte slice. +func SurfaceInfoListBytes(buf []byte, list []SurfaceInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Card32' + +// CreateContextCookie is a cookie used only for CreateContext requests. +type CreateContextCookie struct { + *xgb.Cookie +} + +// CreateContext sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateContextCookie.Reply() +func CreateContext(c *xgb.Conn, ContextId Context, PortId xv.Port, SurfaceId Surface, Width uint16, Height uint16, Flags uint32) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createContextRequest(c, ContextId, PortId, SurfaceId, Width, Height, Flags), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateContextUnchecked(c *xgb.Conn, ContextId Context, PortId xv.Port, SurfaceId Surface, Width uint16, Height uint16, Flags uint32) CreateContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'CreateContext' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createContextRequest(c, ContextId, PortId, SurfaceId, Width, Height, Flags), cookie) + return CreateContextCookie{cookie} +} + +// CreateContextReply represents the data returned from a CreateContext request. +type CreateContextReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + WidthActual uint16 + HeightActual uint16 + FlagsReturn uint32 + // padding: 20 bytes + PrivData []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a CreateContext request. +func (cook CreateContextCookie) Reply() (*CreateContextReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createContextReply(buf), nil +} + +// createContextReply reads a byte slice into a CreateContextReply value. +func createContextReply(buf []byte) *CreateContextReply { + v := new(CreateContextReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.WidthActual = xgb.Get16(buf[b:]) + b += 2 + + v.HeightActual = xgb.Get16(buf[b:]) + b += 2 + + v.FlagsReturn = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.PrivData = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.PrivData[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for CreateContext +// createContextRequest writes a CreateContext request to a byte slice. +func createContextRequest(c *xgb.Conn, ContextId Context, PortId xv.Port, SurfaceId Surface, Width uint16, Height uint16, Flags uint32) []byte { + size := 24 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 2 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextId)) + b += 4 + + xgb.Put32(buf[b:], uint32(PortId)) + b += 4 + + xgb.Put32(buf[b:], uint32(SurfaceId)) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + xgb.Put32(buf[b:], Flags) + b += 4 + + return buf +} + +// CreateSubpictureCookie is a cookie used only for CreateSubpicture requests. +type CreateSubpictureCookie struct { + *xgb.Cookie +} + +// CreateSubpicture sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateSubpictureCookie.Reply() +func CreateSubpicture(c *xgb.Conn, SubpictureId Subpicture, Context Context, XvimageId uint32, Width uint16, Height uint16) CreateSubpictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'CreateSubpicture' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createSubpictureRequest(c, SubpictureId, Context, XvimageId, Width, Height), cookie) + return CreateSubpictureCookie{cookie} +} + +// CreateSubpictureUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateSubpictureUnchecked(c *xgb.Conn, SubpictureId Subpicture, Context Context, XvimageId uint32, Width uint16, Height uint16) CreateSubpictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'CreateSubpicture' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createSubpictureRequest(c, SubpictureId, Context, XvimageId, Width, Height), cookie) + return CreateSubpictureCookie{cookie} +} + +// CreateSubpictureReply represents the data returned from a CreateSubpicture request. +type CreateSubpictureReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + WidthActual uint16 + HeightActual uint16 + NumPaletteEntries uint16 + EntryBytes uint16 + ComponentOrder []byte // size: 4 + // padding: 12 bytes + PrivData []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a CreateSubpicture request. +func (cook CreateSubpictureCookie) Reply() (*CreateSubpictureReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createSubpictureReply(buf), nil +} + +// createSubpictureReply reads a byte slice into a CreateSubpictureReply value. +func createSubpictureReply(buf []byte) *CreateSubpictureReply { + v := new(CreateSubpictureReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.WidthActual = xgb.Get16(buf[b:]) + b += 2 + + v.HeightActual = xgb.Get16(buf[b:]) + b += 2 + + v.NumPaletteEntries = xgb.Get16(buf[b:]) + b += 2 + + v.EntryBytes = xgb.Get16(buf[b:]) + b += 2 + + v.ComponentOrder = make([]byte, 4) + copy(v.ComponentOrder[:4], buf[b:]) + b += int(4) + + b += 12 // padding + + v.PrivData = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.PrivData[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for CreateSubpicture +// createSubpictureRequest writes a CreateSubpicture request to a byte slice. +func createSubpictureRequest(c *xgb.Conn, SubpictureId Subpicture, Context Context, XvimageId uint32, Width uint16, Height uint16) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 6 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SubpictureId)) + b += 4 + + xgb.Put32(buf[b:], uint32(Context)) + b += 4 + + xgb.Put32(buf[b:], XvimageId) + b += 4 + + xgb.Put16(buf[b:], Width) + b += 2 + + xgb.Put16(buf[b:], Height) + b += 2 + + return buf +} + +// CreateSurfaceCookie is a cookie used only for CreateSurface requests. +type CreateSurfaceCookie struct { + *xgb.Cookie +} + +// CreateSurface sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateSurfaceCookie.Reply() +func CreateSurface(c *xgb.Conn, SurfaceId Surface, ContextId Context) CreateSurfaceCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'CreateSurface' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createSurfaceRequest(c, SurfaceId, ContextId), cookie) + return CreateSurfaceCookie{cookie} +} + +// CreateSurfaceUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateSurfaceUnchecked(c *xgb.Conn, SurfaceId Surface, ContextId Context) CreateSurfaceCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'CreateSurface' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createSurfaceRequest(c, SurfaceId, ContextId), cookie) + return CreateSurfaceCookie{cookie} +} + +// CreateSurfaceReply represents the data returned from a CreateSurface request. +type CreateSurfaceReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + // padding: 24 bytes + PrivData []uint32 // size: xgb.Pad((int(Length) * 4)) +} + +// Reply blocks and returns the reply data for a CreateSurface request. +func (cook CreateSurfaceCookie) Reply() (*CreateSurfaceReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createSurfaceReply(buf), nil +} + +// createSurfaceReply reads a byte slice into a CreateSurfaceReply value. +func createSurfaceReply(buf []byte) *CreateSurfaceReply { + v := new(CreateSurfaceReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + v.PrivData = make([]uint32, v.Length) + for i := 0; i < int(v.Length); i++ { + v.PrivData[i] = xgb.Get32(buf[b:]) + b += 4 + } + + return v +} + +// Write request to wire for CreateSurface +// createSurfaceRequest writes a CreateSurface request to a byte slice. +func createSurfaceRequest(c *xgb.Conn, SurfaceId Surface, ContextId Context) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 4 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SurfaceId)) + b += 4 + + xgb.Put32(buf[b:], uint32(ContextId)) + b += 4 + + return buf +} + +// DestroyContextCookie is a cookie used only for DestroyContext requests. +type DestroyContextCookie struct { + *xgb.Cookie +} + +// DestroyContext sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyContext(c *xgb.Conn, ContextId Context) DestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'DestroyContext' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyContextRequest(c, ContextId), cookie) + return DestroyContextCookie{cookie} +} + +// DestroyContextChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyContextCookie.Check() +func DestroyContextChecked(c *xgb.Conn, ContextId Context) DestroyContextCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'DestroyContext' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyContextRequest(c, ContextId), cookie) + return DestroyContextCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroyContextCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyContext +// destroyContextRequest writes a DestroyContext request to a byte slice. +func destroyContextRequest(c *xgb.Conn, ContextId Context) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 3 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextId)) + b += 4 + + return buf +} + +// DestroySubpictureCookie is a cookie used only for DestroySubpicture requests. +type DestroySubpictureCookie struct { + *xgb.Cookie +} + +// DestroySubpicture sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroySubpicture(c *xgb.Conn, SubpictureId Subpicture) DestroySubpictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'DestroySubpicture' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroySubpictureRequest(c, SubpictureId), cookie) + return DestroySubpictureCookie{cookie} +} + +// DestroySubpictureChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroySubpictureCookie.Check() +func DestroySubpictureChecked(c *xgb.Conn, SubpictureId Subpicture) DestroySubpictureCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'DestroySubpicture' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroySubpictureRequest(c, SubpictureId), cookie) + return DestroySubpictureCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroySubpictureCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroySubpicture +// destroySubpictureRequest writes a DestroySubpicture request to a byte slice. +func destroySubpictureRequest(c *xgb.Conn, SubpictureId Subpicture) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 7 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SubpictureId)) + b += 4 + + return buf +} + +// DestroySurfaceCookie is a cookie used only for DestroySurface requests. +type DestroySurfaceCookie struct { + *xgb.Cookie +} + +// DestroySurface sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroySurface(c *xgb.Conn, SurfaceId Surface) DestroySurfaceCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'DestroySurface' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroySurfaceRequest(c, SurfaceId), cookie) + return DestroySurfaceCookie{cookie} +} + +// DestroySurfaceChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroySurfaceCookie.Check() +func DestroySurfaceChecked(c *xgb.Conn, SurfaceId Surface) DestroySurfaceCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'DestroySurface' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroySurfaceRequest(c, SurfaceId), cookie) + return DestroySurfaceCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DestroySurfaceCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroySurface +// destroySurfaceRequest writes a DestroySurface request to a byte slice. +func destroySurfaceRequest(c *xgb.Conn, SurfaceId Surface) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 5 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(SurfaceId)) + b += 4 + + return buf +} + +// ListSubpictureTypesCookie is a cookie used only for ListSubpictureTypes requests. +type ListSubpictureTypesCookie struct { + *xgb.Cookie +} + +// ListSubpictureTypes sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListSubpictureTypesCookie.Reply() +func ListSubpictureTypes(c *xgb.Conn, PortId xv.Port, SurfaceId Surface) ListSubpictureTypesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'ListSubpictureTypes' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listSubpictureTypesRequest(c, PortId, SurfaceId), cookie) + return ListSubpictureTypesCookie{cookie} +} + +// ListSubpictureTypesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListSubpictureTypesUnchecked(c *xgb.Conn, PortId xv.Port, SurfaceId Surface) ListSubpictureTypesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'ListSubpictureTypes' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listSubpictureTypesRequest(c, PortId, SurfaceId), cookie) + return ListSubpictureTypesCookie{cookie} +} + +// ListSubpictureTypesReply represents the data returned from a ListSubpictureTypes request. +type ListSubpictureTypesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Num uint32 + // padding: 20 bytes + Types []xv.ImageFormatInfo // size: xv.ImageFormatInfoListSize(Types) +} + +// Reply blocks and returns the reply data for a ListSubpictureTypes request. +func (cook ListSubpictureTypesCookie) Reply() (*ListSubpictureTypesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listSubpictureTypesReply(buf), nil +} + +// listSubpictureTypesReply reads a byte slice into a ListSubpictureTypesReply value. +func listSubpictureTypesReply(buf []byte) *ListSubpictureTypesReply { + v := new(ListSubpictureTypesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Num = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Types = make([]xv.ImageFormatInfo, v.Num) + b += xv.ImageFormatInfoReadList(buf[b:], v.Types) + + return v +} + +// Write request to wire for ListSubpictureTypes +// listSubpictureTypesRequest writes a ListSubpictureTypes request to a byte slice. +func listSubpictureTypesRequest(c *xgb.Conn, PortId xv.Port, SurfaceId Surface) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 8 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(PortId)) + b += 4 + + xgb.Put32(buf[b:], uint32(SurfaceId)) + b += 4 + + return buf +} + +// ListSurfaceTypesCookie is a cookie used only for ListSurfaceTypes requests. +type ListSurfaceTypesCookie struct { + *xgb.Cookie +} + +// ListSurfaceTypes sends a checked request. +// If an error occurs, it will be returned with the reply by calling ListSurfaceTypesCookie.Reply() +func ListSurfaceTypes(c *xgb.Conn, PortId xv.Port) ListSurfaceTypesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'ListSurfaceTypes' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(listSurfaceTypesRequest(c, PortId), cookie) + return ListSurfaceTypesCookie{cookie} +} + +// ListSurfaceTypesUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ListSurfaceTypesUnchecked(c *xgb.Conn, PortId xv.Port) ListSurfaceTypesCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'ListSurfaceTypes' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(listSurfaceTypesRequest(c, PortId), cookie) + return ListSurfaceTypesCookie{cookie} +} + +// ListSurfaceTypesReply represents the data returned from a ListSurfaceTypes request. +type ListSurfaceTypesReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Num uint32 + // padding: 20 bytes + Surfaces []SurfaceInfo // size: xgb.Pad((int(Num) * 24)) +} + +// Reply blocks and returns the reply data for a ListSurfaceTypes request. +func (cook ListSurfaceTypesCookie) Reply() (*ListSurfaceTypesReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return listSurfaceTypesReply(buf), nil +} + +// listSurfaceTypesReply reads a byte slice into a ListSurfaceTypesReply value. +func listSurfaceTypesReply(buf []byte) *ListSurfaceTypesReply { + v := new(ListSurfaceTypesReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Num = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + v.Surfaces = make([]SurfaceInfo, v.Num) + b += SurfaceInfoReadList(buf[b:], v.Surfaces) + + return v +} + +// Write request to wire for ListSurfaceTypes +// listSurfaceTypesRequest writes a ListSurfaceTypes request to a byte slice. +func listSurfaceTypesRequest(c *xgb.Conn, PortId xv.Port) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 1 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(PortId)) + b += 4 + + return buf +} + +// QueryVersionCookie is a cookie used only for QueryVersion requests. +type QueryVersionCookie struct { + *xgb.Cookie +} + +// QueryVersion sends a checked request. +// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply() +func QueryVersion(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XVideo-MotionCompensation"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'XVideo-MotionCompensation'. xvmc.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c), cookie) + return QueryVersionCookie{cookie} +} + +// QueryVersionReply represents the data returned from a QueryVersion request. +type QueryVersionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Major uint32 + Minor uint32 +} + +// Reply blocks and returns the reply data for a QueryVersion request. +func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return queryVersionReply(buf), nil +} + +// queryVersionReply reads a byte slice into a QueryVersionReply value. +func queryVersionReply(buf []byte) *QueryVersionReply { + v := new(QueryVersionReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Major = xgb.Get32(buf[b:]) + b += 4 + + v.Minor = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XVideo-MotionCompensation"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 0 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} diff --git a/vend/xgbutil/.gitignore b/vend/xgbutil/.gitignore new file mode 100644 index 0000000..22df4f4 --- /dev/null +++ b/vend/xgbutil/.gitignore @@ -0,0 +1,6 @@ +*.swp +*.png +tst_first +tst_graphics +TAGS + diff --git a/vend/xgbutil/LICENSE b/vend/xgbutil/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/vend/xgbutil/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/vend/xgbutil/Makefile b/vend/xgbutil/Makefile new file mode 100644 index 0000000..a510c83 --- /dev/null +++ b/vend/xgbutil/Makefile @@ -0,0 +1,36 @@ +all: callback.go types_auto.go gofmt + +install: + go install -p 6 . ./ewmh ./gopher ./icccm ./keybind ./motif ./mousebind \ + ./xcursor ./xevent ./xgraphics ./xinerama ./xprop ./xrect ./xwindow + +push: + git push origin master + git push github master + +build-ex: + find ./_examples/ -type d -wholename './_examples/[a-z]*' -print0 \ + | xargs -0 go build -p 6 + +gofmt: + gofmt -w *.go */*.go _examples/*/*.go + colcheck *.go */*.go _examples/*/*.go + +callback.go: + scripts/write-events callbacks > xevent/callback.go + +types_auto.go: + scripts/write-events evtypes > xevent/types_auto.go + +tags: + find ./ \( -name '*.go' -and -not -wholename './tests/*' -and -not -wholename './_examples/*' \) -print0 | xargs -0 gotags > TAGS + +loc: + find ./ -name '*.go' -and -not -wholename './tests*' -and -not -name '*keysymdef.go' -and -not -name '*gopher.go' -print | sort | xargs wc -l + +ex-%: + go run _examples/$*/main.go + +gopherimg: + go-bindata -f GopherPng -p gopher -i gopher/gophercolor-small.png -o gopher/gopher.go + diff --git a/vend/xgbutil/README b/vend/xgbutil/README new file mode 100644 index 0000000..4daa013 --- /dev/null +++ b/vend/xgbutil/README @@ -0,0 +1,61 @@ +xgbutil is a utility library designed to work with the X Go Binding. This +project's main goal is to make various X related tasks easier. For example, +binding keys, using the EWMH or ICCCM specs with the window manager, +moving/resizing windows, assigning function callbacks to particular events, +drawing images to a window, etc. + +xgbutil attempts to be thread safe, but it has not been completely tested in +this regard. In general, the X event loop implemented in the xevent package is +sequential. The idea is to be sequential by default, and let the user spawn +concurrent code at their discretion. (i.e., the complexity of making the main +event loop generally concurrent is vast.) + +You may sleep safely at night by assuming that XGB is thread safe, though. + +To start using xgbutil, you should have at least a passing familiarity with X. +Your first stop should be the examples directory. + +Installation +============ +go get github.com/jezek/xgbutil + +Dependencies +============ +XGB is the main dependency. Use of the xgraphics packages requires graphics-go +and freetype-go. + +XGB project URL: https://github.com/jezek/xgb +graphics-go project URL: https://github.com/BurntSushi/graphics-go +freetype-go project URL: https://github.com/BurntSushi/freetype-go + +Quick Example +============= +go get github.com/jezek/xgbutil/_examples/window-name-sizes +"$GOPATH"/bin/window-name-sizes + +The output will be a list of names of all top-level windows and their geometry +including window manager decorations. (Assuming your window manager supports +some basic EWMH properties.) + +Documentation +============= +https://godoc.org/github.com/jezek/xgbutil + +Examples +======== +There are several examples in the examples directory covering common use cases. +They are heavily documented and should run out of the box. + +Python +====== +An older project of mine (BurntSushi), xpybutil, served as inspiration for xgbutil. If you +want to use Python, xpybutil should help quite a bit. Please note though, that +at this point, xgbutil provides a lot more functionality and is much better +documented. + +xpybutil project URL: https://github.com/BurntSushi/xpybutil + +jezek's Fork +============ +Why I've forked the xgbutil repository from BurntSushi's github is discussed in [issue #2](https://github.com/jezek/xgb/issues/2). +I've also changed the LICENSE to GNU GPL v3 to meet the requirements for pkg.go.dev diff --git a/vend/xgbutil/STYLE b/vend/xgbutil/STYLE new file mode 100644 index 0000000..b827c3c --- /dev/null +++ b/vend/xgbutil/STYLE @@ -0,0 +1,29 @@ +I like to keep all my code to 80 columns or less. I have plenty of screen real +estate, but enjoy 80 columns so that I can have multiple code windows open side +to side and not be plagued by the ugly auto-wrapping of a text editor. + +If you don't oblige me, I will fix any patch you submit to abide 80 columns. + +Note that this style restriction does not preclude gofmt, but introduces a few +peculiarities. The first is that gofmt will occasionally add spacing (typically +to comments) that ends up going over 80 columns. Either shorten the comment or +put it on its own line. + +The second and more common hiccup is when a function definition extends beyond +80 columns. If one adds line breaks to keep it below 80 columns, gofmt will +indent all subsequent lines in a function definition to the same indentation +level of the function body. This results in a less-than-ideal separation +between function definition and function body. To remedy this, simply add a +line break like so: + + func RestackWindowExtra(xu *xgbutil.XUtil, win xproto.Window, stackMode int, + sibling xproto.Window, source int) error { + + return ClientEvent(xu, win, "_NET_RESTACK_WINDOW", source, int(sibling), + stackMode) + } + +Something similar should also be applied to long 'if' or 'for' conditionals, +although it would probably be preferrable to break up the conditional to +smaller chunks with a few helper variables. + diff --git a/vend/xgbutil/_examples/change-cursor/main.go b/vend/xgbutil/_examples/change-cursor/main.go new file mode 100644 index 0000000..611a843 --- /dev/null +++ b/vend/xgbutil/_examples/change-cursor/main.go @@ -0,0 +1,63 @@ +// Example change-cursor shows how to use the cursor package to change the +// X cursor in a particular window. To see the new cursor, move your cursor +// into the window created by this program. +// Note that this only shows how to use one of the pre-defined cursors built +// into X using the "cursor" font. Creating your own cursor with your own +// image is a bit more complex, and probably not an instructive example. +// +// While this example shows how to set a cursor in an entire window, the cursor +// value returned from xcursor.CreateCursor[Extra] can be used in pointer +// grab requests too. (So that the cursor changes during the grab.) +package main + +import ( + "log" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xcursor" + "github.com/jezek/xgbutil/xwindow" +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Create the cursor. You can find a list of available cursors in + // xcursor/cursordef.go. + // We'll make an umbrella here, with an orange foreground and a blue + // background. (The background it typically the outline of the cursor.) + // Note that each component of the RGB color is a 16 bit color. I think + // using the most significant byte to specify each component is good + // enough. + cursor, err := xcursor.CreateCursorExtra(X, xcursor.Umbrella, + 0xff00, 0x5500, 0x0000, + 0x3300, 0x6600, 0xff00) + if err != nil { + log.Fatal(err) + } + + // Create a new window. In the create window request, we'll set the + // background color and set the cursor we created above. + // This results in changing the cursor only when it moves into this window. + win, err := xwindow.Generate(X) + if err != nil { + log.Fatal(err) + } + win.Create(X.RootWin(), 0, 0, 500, 500, + xproto.CwBackPixel|xproto.CwCursor, + 0xffffffff, uint32(cursor)) + win.Map() + + // We can free the cursor now that we've set it. + // If you plan on using this cursor again, then it shouldn't be freed. + // (i.e., if you try to free this before setting it as the cursor in a + // window, you'll get a BadCursor error when trying to use it.) + xproto.FreeCursor(X.Conn(), cursor) + + // Block. No need to process any events. + select {} +} diff --git a/vend/xgbutil/_examples/compress-events/main.go b/vend/xgbutil/_examples/compress-events/main.go new file mode 100644 index 0000000..1ff7b5b --- /dev/null +++ b/vend/xgbutil/_examples/compress-events/main.go @@ -0,0 +1,176 @@ +/* +Example compress-events shows how to manipulate the xevent package's event +queue to compress events that arrive more often than you'd like to process +them. This example in particular shows how to compress MotionNotify events, +but the same approach could be used to compress ConfigureNotify events. + +Note that we show the difference between compressed and uncompressed +MotionNotify events by displaying two windows that listen for MotionNotify +events. The green window compresses them while the red window does not. +Hovering over each window will print the x and y positions in each +MotionNotify event received. You should notice that the red window +lags behind the pointer (particularly if you moved the pointer quickly in +and out of the window) while the green window always keeps up, regardless +of the speed of the pointer. + +In each case, we simulate work by sleeping for some amount of time. (The +whole point of compressing events is that there is too much work to be done +for each event.) + +Note that when compressing events, you should always make sure that the +event you're compressing *ought* to be compressed. For example, with +MotionNotify events, if the Event field changes, then it applies to a +different window and probably shouldn't be compressed with MotionNotify +events for other windows. + +Finally, compressing events implicitly assumes that the event handler doing +the compression is the *only* event handler for a particular (event, window) +tuple. If there is more than one event handler for a single (event, window) +tuple and one of them does compression, the other will be left out in the +cold. (Since the main event loop is subverted and won't process the +compressed events in the usual way.) + +N.B. This functionality isn't included in xgbutil because event compression +isn't something that is always desirable, and the conditions under which +compression happens can vary. In particular, compressing ConfigureRequest +events from the perspective of the window manager can be faulty, since +changes to other properties (like WM_NORMAL_HINTS) can change the semantics +of a ConfigureRequest event. (i.e., your compression would need to +specifically look for events that could change future ConfigureRequest +events.) +*/ +package main + +import ( + "fmt" + "log" + "time" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xwindow" +) + +// workTime is the amount of time to sleep to simulate "work" in response to +// MotionNotify events. Increasing this will exacerbate the difference +// between the green and red windows. But if you increase it too much, +// the red window starts to *really* lag, and you'll probably have to kill +// the program. +var workTime = 50 * time.Millisecond + +// newWindow creates a new window that listens to MotionNotify events with +// the given backgroundcolor. +func newWindow(X *xgbutil.XUtil, color uint32) *xwindow.Window { + win, err := xwindow.Generate(X) + if err != nil { + log.Fatal(err) + } + + err = win.CreateChecked(X.RootWin(), 0, 0, 400, 400, + xproto.CwBackPixel|xproto.CwEventMask, + color, xproto.EventMaskPointerMotion) + if err != nil { + log.Fatal(err) + } + + win.Map() + return win +} + +// compressMotionNotify takes a MotionNotify event, and inspects the event +// queue for any future MotionNotify events that can be received without +// blocking. The most recent MotionNotify event is then returned. +// Note that we need to make sure that the Event, Child, Detail, State, Root +// and SameScreen fields are the same to ensure the same window/action is +// generating events. That is, we are only compressing the RootX, RootY, +// EventX and EventY fields. +// This function is not thread safe, since Peek returns a *copy* of the +// event queue---which could be out of date by the time we dequeue events. +func compressMotionNotify(X *xgbutil.XUtil, + ev xevent.MotionNotifyEvent) xevent.MotionNotifyEvent { + + // We force a round trip request so that we make sure to read all + // available events. + X.Sync() + xevent.Read(X, false) + + // The most recent MotionNotify event that we'll end up returning. + laste := ev + + // Look through each event in the queue. If it's an event and it matches + // all the fields in 'ev' that are detailed above, then set it to 'laste'. + // In which case, we'll also dequeue the event, otherwise it will be + // processed twice! + // N.B. If our only goal was to find the most recent relevant MotionNotify + // event, we could traverse the event queue backwards and simply use + // the first MotionNotify we see. However, this could potentially leave + // other MotionNotify events in the queue, which we *don't* want to be + // processed. So we stride along and just pick off MotionNotify events + // until we don't see any more. + for i, ee := range xevent.Peek(X) { + if ee.Err != nil { // This is an error, skip it. + continue + } + + // Use type assertion to make sure this is a MotionNotify event. + if mn, ok := ee.Event.(xproto.MotionNotifyEvent); ok { + // Now make sure all appropriate fields are equivalent. + if ev.Event == mn.Event && ev.Child == mn.Child && + ev.Detail == mn.Detail && ev.State == mn.State && + ev.Root == mn.Root && ev.SameScreen == mn.SameScreen { + + // Set the most recent/valid motion notify event. + laste = xevent.MotionNotifyEvent{&mn} + + // We cheat and use the stack semantics of defer to dequeue + // most recent motion notify events first, so that the indices + // don't become invalid. (If we dequeued oldest first, we'd + // have to account for all future events shifting to the left + // by one.) + defer func(i int) { xevent.DequeueAt(X, i) }(i) + } + } + } + + // This isn't strictly necessary, but is correct. We should update + // xgbutil's sense of time with the most recent event processed. + // This is typically done in the main event loop, but since we are + // subverting the main event loop, we should take care of it. + X.TimeSet(laste.Time) + + return laste +} + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Create window for receiving compressed MotionNotify events. + cwin := newWindow(X, 0x00ff00) + + // Attach event handler for MotionNotify that compresses events. + xevent.MotionNotifyFun( + func(X *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { + ev = compressMotionNotify(X, ev) + fmt.Printf("COMPRESSED: (EventX %d, EventY %d)\n", + ev.EventX, ev.EventY) + time.Sleep(workTime) + }).Connect(X, cwin.Id) + + // Create window for receiving uncompressed MotionNotify events. + uwin := newWindow(X, 0xff0000) + + // Attach event handler for MotionNotify that does not compress events. + xevent.MotionNotifyFun( + func(X *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { + fmt.Printf("UNCOMPRESSED: (EventX %d, EventY %d)\n", + ev.EventX, ev.EventY) + time.Sleep(workTime) + }).Connect(X, uwin.Id) + + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/doc.go b/vend/xgbutil/_examples/doc.go new file mode 100644 index 0000000..5214be8 --- /dev/null +++ b/vend/xgbutil/_examples/doc.go @@ -0,0 +1,20 @@ +/* +Package examples contains several complete examples depicting some common use +cases of xgbutil. + +The examples included are designed to either demonstrate how a particular +facility of xgbutil works, or how to accomplish some common goal when using X. + +For example, example simple-keybinding demonstrates how to use xgbutil to +respond to particular key presses while example graceful-window-close shows +how to close windows without killing your connection to X. + +My goal is that each example demonstrates one thing, although the nature of X +typically requires some amount of boilerplate so that some examples are a bit +more bloated than I would like. + +If you have any suggestions for other examples to include, I'd be happy to hear +them. You may post them at the main project page: +https://github.com/jezek/xgbutil. +*/ +package documentation diff --git a/vend/xgbutil/_examples/draw-text/main.go b/vend/xgbutil/_examples/draw-text/main.go new file mode 100644 index 0000000..bbaa132 --- /dev/null +++ b/vend/xgbutil/_examples/draw-text/main.go @@ -0,0 +1,91 @@ +// Example draw-text shows how to draw text to an xgraphics.Image type. +package main + +import ( + "image" + "log" + "os" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" +) + +var ( + // The geometry of the canvas to draw text on. + canvasWidth, canvasHeight = 600, 100 + + // The background color of the canvas. + bg = xgraphics.BGRA{B: 0xff, G: 0x66, R: 0x33, A: 0xff} + + // The path to the font used to draw text. + fontPath = "/usr/share/fonts/TTF/FreeMonoBold.ttf" + + // The color of the text. + fg = xgraphics.BGRA{B: 0xff, G: 0xff, R: 0xff, A: 0xff} + + // The size of the text. + size = 20.0 + + // The text to draw. + msg = "This is some text drawn by xgraphics!" +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Load some font. You may need to change the path depending upon your + // system configuration. + fontReader, err := os.Open(fontPath) + if err != nil { + log.Fatal(err) + } + + // Now parse the font. + font, err := xgraphics.ParseFont(fontReader) + if err != nil { + log.Fatal(err) + } + + // Create some canvas. + ximg := xgraphics.New(X, image.Rect(0, 0, canvasWidth, canvasHeight)) + ximg.For(func(x, y int) xgraphics.BGRA { + return bg + }) + + // Now write the text. + _, _, err = ximg.Text(10, 10, fg, size, font, msg) + if err != nil { + log.Fatal(err) + } + + // Compute extents of first line of text. + _, firsth := xgraphics.Extents(font, size, msg) + + // Now show the image in its own window. + win := ximg.XShowExtra("Drawing text using xgraphics", true) + + // Now draw some more text below the above and demonstrate how to update + // only the region we've updated. + _, _, err = ximg.Text(10, 10+firsth, fg, size, font, "Some more text.") + if err != nil { + log.Fatal(err) + } + + // Now compute extents of the second line of text, so we know which region + // to update. + secw, sech := xgraphics.Extents(font, size, "Some more text.") + + // Now repaint on the region that we drew text on. Then update the screen. + bounds := image.Rect(10, 10+firsth, 10+secw, 10+firsth+sech) + ximg.SubImage(bounds).(*xgraphics.Image).XDraw() + ximg.XPaint(win.Id) + + // All we really need to do is block, which could be achieved using + // 'select{}'. Invoking the main event loop however, will emit error + // message if anything went seriously wrong above. + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/fullscreen/main.go b/vend/xgbutil/_examples/fullscreen/main.go new file mode 100644 index 0000000..34dab2d --- /dev/null +++ b/vend/xgbutil/_examples/fullscreen/main.go @@ -0,0 +1,136 @@ +// Example fullscreen shows how to make a window showing the Go Gopher go +// fullscreen and back using keybindings and EWMH. +package main + +import ( + "bytes" + "image" + _ "image/png" + "log" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/gopher" + "github.com/jezek/xgbutil/icccm" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/mousebind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" + "github.com/jezek/xgbutil/xwindow" +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + keybind.Initialize(X) // call once before using keybind package + + // Read an example gopher image into a regular png image. + img, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng())) + if err != nil { + log.Fatal(err) + } + + // Now convert it into an X image. + ximg := xgraphics.NewConvert(X, img) + + // Now show it in a new window. + // We set the window title and tell the program to quit gracefully when + // the window is closed. + // There is also a convenience method, XShow, that requires no parameters. + win := showImage(ximg, "The Go Gopher!", true) + + // Listen for key press events. + win.Listen(xproto.EventMaskKeyPress) + + err = keybind.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + println("fullscreen!") + err := ewmh.WmStateReq(X, win.Id, ewmh.StateToggle, + "_NET_WM_STATE_FULLSCREEN") + if err != nil { + log.Fatal(err) + } + }).Connect(X, win.Id, "f", false) + if err != nil { + log.Fatal(err) + } + + err = keybind.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + println("quit fullscreen!") + err := ewmh.WmStateReq(X, win.Id, ewmh.StateToggle, + "_NET_WM_STATE_FULLSCREEN") + if err != nil { + log.Fatal(err) + } + }).Connect(X, win.Id, "Escape", false) + if err != nil { + log.Fatal(err) + } + + // If we don't block, the program will end and the window will disappear. + // We could use a 'select{}' here, but xevent.Main will emit errors if + // something went wrong, so use that instead. + xevent.Main(X) +} + +// This is a slightly modified version of xgraphics.XShowExtra that does +// not set any resize constraints on the window (so that it can go +// fullscreen). +func showImage(im *xgraphics.Image, name string, quit bool) *xwindow.Window { + if len(name) == 0 { + name = "xgbutil Image Window" + } + w, h := im.Rect.Dx(), im.Rect.Dy() + + win, err := xwindow.Generate(im.X) + if err != nil { + xgbutil.Logger.Printf("Could not generate new window id: %s", err) + return nil + } + + // Create a very simple window with dimensions equal to the image. + win.Create(im.X.RootWin(), 0, 0, w, h, 0) + + // Make this window close gracefully. + win.WMGracefulClose(func(w *xwindow.Window) { + xevent.Detach(w.X, w.Id) + keybind.Detach(w.X, w.Id) + mousebind.Detach(w.X, w.Id) + w.Destroy() + + if quit { + xevent.Quit(w.X) + } + }) + + // Set WM_STATE so it is interpreted as a top-level window. + err = icccm.WmStateSet(im.X, win.Id, &icccm.WmState{ + State: icccm.StateNormal, + }) + if err != nil { // not a fatal error + xgbutil.Logger.Printf("Could not set WM_STATE: %s", err) + } + + // Set _NET_WM_NAME so it looks nice. + err = ewmh.WmNameSet(im.X, win.Id, name) + if err != nil { // not a fatal error + xgbutil.Logger.Printf("Could not set _NET_WM_NAME: %s", err) + } + + // Paint our image before mapping. + im.XSurfaceSet(win.Id) + im.XDraw() + im.XPaint(win.Id) + + // Now we can map, since we've set all our properties. + // (The initial map is when the window manager starts managing.) + win.Map() + + return win +} diff --git a/vend/xgbutil/_examples/graceful-window-close/main.go b/vend/xgbutil/_examples/graceful-window-close/main.go new file mode 100644 index 0000000..aaa159a --- /dev/null +++ b/vend/xgbutil/_examples/graceful-window-close/main.go @@ -0,0 +1,120 @@ +// Example graceful-window-close shows how to create windows that can be closed +// without killing your X connection (and thereby destroying any other windows +// you may have open). This is actually achieved through an ICCCM standard. +// We add the WM_DELETE_WINDOW to the WM_PROTOCOLS property on our window. +// This indicates to well-behaving window managers that a certain kind of +// client message should be sent to our client when the window should be closed. +// If we *don't* add the WM_DELETE_WINDOW to the WM_PROTOCOLS property, the +// window manager will typically call KillClient---which will destroy the +// window and your X connection. +// +// If you click inside one of the windows created, a new window will be +// automatically created. +// +// The program will stop when all windows have been closed. +// +// For more information on the convention used please see +// http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.7 and +// http://tronche.com/gui/x/icccm/sec-4.html#s-4.2.8 +package main + +import ( + "log" + "math/rand" + "os" + "time" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/mousebind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xwindow" +) + +// When counter reaches 0, exit. +var counter int32 + +// Just iniaitlize the RNG seed for generating random background colors. +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// newWindow creates a new window with a random background color. It sets the +// WM_PROTOCOLS property to contain the WM_DELETE_WINDOW atom. It also sets +// up a ClientMessage event handler so that we know when to destroy the window. +// We also set up a mouse binding so that clicking inside a window will +// create another one. +func newWindow(X *xgbutil.XUtil) { + counter++ + win, err := xwindow.Generate(X) + if err != nil { + log.Fatal(err) + } + + // Get a random background color, create the window (ask to receive button + // release events while we're at it) and map the window. + bgColor := rand.Intn(0xffffff + 1) + win.Create(X.RootWin(), 0, 0, 200, 200, + xproto.CwBackPixel|xproto.CwEventMask, + uint32(bgColor), xproto.EventMaskButtonRelease) + + // WMGracefulClose does all of the work for us. It sets the appropriate + // values for WM_PROTOCOLS, and listens for ClientMessages that implement + // the WM_DELETE_WINDOW protocol. When one is found, the provided callback + // is executed. + win.WMGracefulClose( + func(w *xwindow.Window) { + // Detach all event handlers. + // This should always be done when a window can no longer + // receive events. + xevent.Detach(w.X, w.Id) + mousebind.Detach(w.X, w.Id) + w.Destroy() + + // Exit if there are no more windows left. + counter-- + if counter == 0 { + os.Exit(0) + } + }) + + // It's important that the map comes after setting WMGracefulClose, since + // the WM isn't obliged to watch updates to the WM_PROTOCOLS property. + win.Map() + + // A mouse binding so that a left click will spawn a new window. + // Note that we don't issue a grab here. Typically, window managers will + // grab a button press on the client window (which usually activates the + // window), so that we'd end up competing with the window manager if we + // tried to grab it. + // Instead, we set a ButtonRelease mask when creating the window and attach + // a mouse binding *without* a grab. + err = mousebind.ButtonReleaseFun( + func(X *xgbutil.XUtil, ev xevent.ButtonReleaseEvent) { + newWindow(X) + }).Connect(X, win.Id, "1", false, false) + if err != nil { + log.Fatal(err) + } +} + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Anytime the mousebind (keybind) package is used, mousebind.Initialize + // *should* be called once. In the case of the mousebind package, this + // isn't strictly necessary (currently!), but the 'Drag' features of + // the mousebind package won't work without it. + mousebind.Initialize(X) + + // Create two windows to prove we can close one while keeping the + // other alive. + newWindow(X) + newWindow(X) + + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/image-speed/main.go b/vend/xgbutil/_examples/image-speed/main.go new file mode 100644 index 0000000..728844d --- /dev/null +++ b/vend/xgbutil/_examples/image-speed/main.go @@ -0,0 +1,131 @@ +//This demonstration shows drawing entire generated images to an x window +//and calculating the speed of the generation and the drawing operations +//It should be noted that redrawing the entire image is inefficient, this demo +//was made to show me how fast I could draw to the windows with this method. +package main + +import ( + "github.com/jezek/xgb/xproto" + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" + "github.com/jezek/xgbutil/xwindow" + "image" + "log" + "time" +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Println(err) + return + } + + //Initialize the keybind package + keybind.Initialize(X) + + //Create a window + win, err := xwindow.Generate(X) + if err != nil { + log.Fatalf("Could not generate a new window X id: %s", err) + } + win.Create(X.RootWin(), 0, 0, 1024, 768, xproto.CwBackPixel, 0x606060ff) + + // Listen for Key{Press,Release} events. + win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) + + // Map the window. This is what makes it on the screen + win.Map() + + //Make a ...callback... for the events and connect + xevent.KeyPressFun( + func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { + modStr := keybind.ModifierString(e.State) + keyStr := keybind.LookupString(X, e.State, e.Detail) + if len(modStr) > 0 { + log.Printf("Key: %s-%s\n", modStr, keyStr) + } else { + log.Println("Key:", keyStr) + } + + if keybind.KeyMatch(X, "Escape", e.State, e.Detail) { + if e.State&xproto.ModMaskControl > 0 { + log.Println("Control-Escape detected. Quitting...") + xevent.Quit(X) + } + } + }).Connect(X, win.Id) + + //So here i'm going to try to make a image..' + img := xgraphics.New(X, image.Rect(0, 0, 1024, 768)) + + err = img.XSurfaceSet(win.Id) + if err != nil { + log.Printf("Error while setting window surface to image %d: %s\n", + win, err) + } else { + log.Printf("Window %d surface set to image OK\n", win) + } + + // I /think/ XDraw actually sends data to server? + img.XDraw() + // I /think/ XPaint tells the server to paint image to window + img.XPaint(win.Id) + + //Start the routine that updates the window + go updater(img, win) + + //This seems to start a main loop for listening to xevents + xevent.Main(X) +} + +func updater(img *xgraphics.Image, win *xwindow.Window) { + //We keep track of times based on 1024 frames + frame := 0 + start := time.Now() + var genStart, drawStart time.Time + var genTotal, drawTotal time.Duration + + for { + frame = frame + 1 + if frame > 1024 { + frame = 0 + log.Printf("Time elapsed: %s\n", time.Now().Sub(start)) + log.Printf("Time generate: %s\n", genTotal) + log.Printf("Time drawing: %s\n", drawTotal) + start = time.Now() + drawTotal, genTotal = 0, 0 + } + + genStart = time.Now() + var x, y, i int + for y = 0; y < 768; y++ { + //set last pixel back to black + img.SetBGRA(frame-1, y, xgraphics.BGRA{0, 0, 0, 255}) + for i = 0; i < 10; i++ { + x = i + frame + if x > 1024 { + x = 1024 + } + img.SetBGRA(x, y, xgraphics.BGRA{0, 0, 255, 255}) + } + } + genTotal += time.Now().Sub(genStart) + + drawStart = time.Now() + //hopefully using checked will block us from drawing again before x + //draws although XDraw might block anyway, we can check for an error + //here + err := img.XDrawChecked() + if err != nil { + log.Println(err) + return + } + //img.XDraw() + + img.XPaint(win.Id) + drawTotal += time.Now().Sub(drawStart) + } +} diff --git a/vend/xgbutil/_examples/keypress-english/main.go b/vend/xgbutil/_examples/keypress-english/main.go new file mode 100644 index 0000000..f4a8a3e --- /dev/null +++ b/vend/xgbutil/_examples/keypress-english/main.go @@ -0,0 +1,103 @@ +// Example keypress-english shows how to convert the State (modifiers) and +// Detail (keycode) members of Key{Press,Release} events to an english +// string representation. +package main + +import ( + "flag" + "log" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xwindow" +) + +var flagRoot = false + +func init() { + log.SetFlags(0) + flag.BoolVar(&flagRoot, "root", flagRoot, + "When set, the keyboard will be grabbed on the root window. "+ + "Make sure you have a way to kill the window created with "+ + "the mouse.") + flag.Parse() +} + +func main() { + + // Connect to the X server using the DISPLAY environment variable. + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Anytime the keybind (mousebind) package is used, keybind.Initialize + // *should* be called once. It isn't strictly necessary, but allows your + // keybindings to persist even if the keyboard mapping is changed during + // run-time. (Assuming you're using the xevent package's event loop.) + // It also handles the case when your modifier map is changed. + keybind.Initialize(X) + + // Create a new window. We will listen for key presses and translate them + // only when this window is in focus. (Similar to how `xev` works.) + win, err := xwindow.Generate(X) + if err != nil { + log.Fatalf("Could not generate a new window X id: %s", err) + } + win.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel, 0xffffffff) + + // Listen for Key{Press,Release} events. + win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) + + // Map the window. + win.Map() + + // Notice that we use xevent.KeyPressFun instead of keybind.KeyPressFun, + // because we aren't trying to make a grab *and* because we want to listen + // to *all* key press events, rather than just a particular key sequence + // that has been pressed. + wid := win.Id + if flagRoot { + wid = X.RootWin() + } + xevent.KeyPressFun( + func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { + // keybind.LookupString does the magic of implementing parts of + // the X Keyboard Encoding to determine an english representation + // of the modifiers/keycode tuple. + // N.B. It's working for me, but probably isn't 100% correct in + // all environments yet. + modStr := keybind.ModifierString(e.State) + keyStr := keybind.LookupString(X, e.State, e.Detail) + if len(modStr) > 0 { + log.Printf("Key: %s-%s\n", modStr, keyStr) + } else { + log.Println("Key:", keyStr) + } + + if keybind.KeyMatch(X, "Escape", e.State, e.Detail) { + if e.State&xproto.ModMaskControl > 0 { + log.Println("Control-Escape detected. Quitting...") + xevent.Quit(X) + } + } + }).Connect(X, wid) + + // If we want root, then we take over the entire keyboard. + if flagRoot { + if err := keybind.GrabKeyboard(X, X.RootWin()); err != nil { + log.Fatalf("Could not grab keyboard: %s", err) + } + log.Println("WARNING: We are taking *complete* control of the root " + + "window. The only way out is to press 'Control + Escape' or to " + + "close the window with the mouse.") + } + + // Finally, start the main event loop. This will route any appropriate + // KeyPressEvents to your callback function. + log.Println("Program initialized. Start pressing keys!") + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/multiple-source-event-loop/main.go b/vend/xgbutil/_examples/multiple-source-event-loop/main.go new file mode 100644 index 0000000..19726ad --- /dev/null +++ b/vend/xgbutil/_examples/multiple-source-event-loop/main.go @@ -0,0 +1,93 @@ +// Example multiple-source-event-loop shows how to use the xevent package to +// combine multiple sources in your main event loop. This is particularly +// useful if your application can respond to user input from other sources. +package main + +import ( + "fmt" + "log" + "time" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xprop" + "github.com/jezek/xgbutil/xwindow" +) + +// otherSource serves as a placeholder from some other source of user input. +func otherSource() chan int { + c := make(chan int, 0) + go func() { + defer close(c) + + i := 1 + for { + c <- i + i++ + time.Sleep(time.Second) + } + }() + return c +} + +// sendClientMessages is a goroutine that sends client messages to the root +// window. We then listen to them later as a demonstration of responding to +// X events. (They are sent with SubstructureNotify and SubstructureRedirect +// masks set. So in order to receive them, we'll have to explicitly listen +// to events of that type on the root window.) +func xSource(X *xgbutil.XUtil) { + i := 1 + for { + ewmh.ClientEvent(X, X.RootWin(), "NOOP", i) + i++ + time.Sleep(200 * time.Millisecond) + } +} + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Start generating other source events. + otherChan := otherSource() + + // Start generating X events (by sending client messages to root window). + go xSource(X) + + // Listen to those X events. + xwindow.New(X, X.RootWin()).Listen(xproto.EventMaskSubstructureNotify) + + // Respond to those X events. + xevent.ClientMessageFun( + func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { + atmName, err := xprop.AtomName(X, ev.Type) + if err != nil { + log.Fatal(err) + } + fmt.Printf("ClientMessage: %d. %s\n", ev.Data.Data32[0], atmName) + }).Connect(X, X.RootWin()) + + // Instead of using the usual xevent.Main, we use xevent.MainPing. + // It runs the main event loop inside a goroutine and returns ping + // channels, which are sent benign values right before an event is + // dequeued and right after that event has finished running all callbacks + // associated with it, respectively. + pingBefore, pingAfter, pingQuit := xevent.MainPing(X) + for { + select { + case <-pingBefore: + // Wait for the event to finish processing. + <-pingAfter + case otherVal := <-otherChan: + fmt.Printf("Processing other event: %d\n", otherVal) + case <-pingQuit: + fmt.Printf("xevent loop has quit") + return + } + } +} diff --git a/vend/xgbutil/_examples/pointer-painting/main.go b/vend/xgbutil/_examples/pointer-painting/main.go new file mode 100644 index 0000000..d585e62 --- /dev/null +++ b/vend/xgbutil/_examples/pointer-painting/main.go @@ -0,0 +1,268 @@ +// Example pointer-painting shows how to draw on a window, MS Paint style. +// This is an extremely involved example, but it showcases a lot of xgbutil +// and how pieces of it can be tied together. +// +// If you're just starting with xgbutil, I highly recommend checking out the +// other examples before attempting to digest this one. +package main + +import ( + "bytes" + "fmt" + "image" + _ "image/png" + "log" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/gopher" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/mousebind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" + "github.com/jezek/xgbutil/xwindow" +) + +var ( + // The color to use for the background. + bg = xgraphics.BGRA{0x0, 0x0, 0x0, 0xff} + + // Different colors for drawing. + // The keys represent the key sequences that must be pressed to + // switch to the color value. + pencils = map[string]xgraphics.BGRA{ + "1": xgraphics.BGRA{0xff, 0xff, 0xff, 0xff}, // white + "2": xgraphics.BGRA{0xff, 0x0, 0x0, 0xff}, // blue + "3": xgraphics.BGRA{0x0, 0xff, 0x0, 0xff}, // green + "4": xgraphics.BGRA{0x0, 0x0, 0xff, 0xff}, // red + "5": xgraphics.BGRA{0x0, 0x7f, 0xff, 0xff}, // orange + "6": xgraphics.BGRA{0xaa, 0x0, 0xff, 0x55}, // transparent pink + } + + // The current pencil color. + pencil = xgraphics.BGRA{0xff, 0xff, 0xff, 0xff} + + // The size of the tip of the pencil, in pixels. + pencilTip = 30 + + // The width and height of the canvas. + width, height = 1000, 1000 + + // The key sequence to use to clear the canvas. + clearKey = "c" + + // Easter egg! Right click to draw a gopher with the following dimensions. + gopherWidth, gopherHeight = 100, 100 +) + +// drawPencil takes an (x, y) position (from a MotionNotify event) and draws +// a rectangle of size pencilTip on to canvas. +func drawPencil(canvas *xgraphics.Image, win *xwindow.Window, x, y int) { + // Create a subimage at (x, y) with pencilTip width and height from canvas. + // Creating subimages is very cheap---no pixels are copied. + // Moreover, when subimages are drawn to the screen, only the pixels in + // the sub-image are sent to X. + tipRect := midRect(x, y, pencilTip, pencilTip, width, height) + + // If the rectangle contains no pixels, don't draw anything. + if tipRect.Empty() { + return + } + + // Output a little message. + log.Printf("Drawing pencil point at (%d, %d)", x, y) + + // Create the subimage of the canvas to draw to. + tip := canvas.SubImage(tipRect).(*xgraphics.Image) + fmt.Println(tip.Rect) + + // Now color each pixel in tip with the pencil color. + tip.For(func(x, y int) xgraphics.BGRA { + return xgraphics.BlendBGRA(tip.At(x, y).(xgraphics.BGRA), pencil) + }) + + // Now draw the changes to the pixmap. + tip.XDraw() + + // And paint them to the window. + tip.XPaint(win.Id) +} + +// drawGopher draws the gopher image to the canvas. +func drawGopher(canvas *xgraphics.Image, gopher image.Image, + win *xwindow.Window, x, y int) { + + // Find the rectangle of the canvas where we're going to draw the gopher. + gopherRect := midRect(x, y, gopherWidth, gopherHeight, width, height) + + // If the rectangle contains no pixels, don't draw anything. + if gopherRect.Empty() { + return + } + + // Output a little message. + log.Printf("Drawing gopher at (%d, %d)", x, y) + + // Get a subimage of the gopher that's in sync with gopherRect. + gopherPt := image.Pt(gopher.Bounds().Min.X, gopher.Bounds().Min.Y) + if gopherRect.Min.X == 0 { + gopherPt.X = gopherWidth - gopherRect.Dx() + } + if gopherRect.Min.Y == 0 { + gopherPt.Y = gopherHeight - gopherRect.Dy() + } + + // Create the canvas subimage. + subCanvas := canvas.SubImage(gopherRect).(*xgraphics.Image) + + // Blend the gopher image into the sub-canvas. + // This does alpha blending. + xgraphics.Blend(subCanvas, gopher, gopherPt) + + // Now draw the changes to the pixmap. + subCanvas.XDraw() + + // And paint them to the window. + subCanvas.XPaint(win.Id) +} + +// clearCanvas erases all your pencil marks. +func clearCanvas(canvas *xgraphics.Image, win *xwindow.Window) { + log.Println("Clearing canvas...") + canvas.For(func(x, y int) xgraphics.BGRA { + return bg + }) + + canvas.XDraw() + canvas.XPaint(win.Id) +} + +func fatal(err error) { + if err != nil { + log.Panic(err) + } +} + +func main() { + X, err := xgbutil.NewConn() + fatal(err) + + // Whenever the mousebind package is used, you must call Initialize. + // Similarly for the keybind package. + keybind.Initialize(X) + mousebind.Initialize(X) + + // Easter egg! Use a right click to draw a gopher. + gopherPng, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng())) + fatal(err) + + // Now scale it to a reasonable size. + gopher := xgraphics.Scale(gopherPng, gopherWidth, gopherHeight) + + // Create a new xgraphics.Image. It automatically creates an X pixmap for + // you, and handles drawing to windows in the XDraw, XPaint and + // XSurfaceSet functions. + // N.B. An error is possible since X pixmap allocation can fail. + canvas := xgraphics.New(X, image.Rect(0, 0, width, height)) + + // Color in the background color. + canvas.For(func(x, y int) xgraphics.BGRA { + return bg + }) + + // Use the convenience function XShowExtra to create and map the + // canvas window. + // XShowExtra will also set the surface window of canvas for us. + // We also use XShowExtra to set the name of the window and to quit the + // main event loop when the window is closed. + win := canvas.XShowExtra("Pointer painting", true) + + // Listen for pointer motion events and key press events. + win.Listen(xproto.EventMaskButtonPress | xproto.EventMaskButtonRelease | + xproto.EventMaskKeyPress) + + // The mousebind drag function runs three callbacks: one when the drag is + // first started, another at each "step" in the drag, and a final one when + // the drag is done. + // The button sequence (in this case '1') is pressed, the first callback + // is executed. If the first return value is true, the drag continues + // and a pointer grab is initiated with the cursor id specified in the + // second return value (use 0 to keep the cursor unchanged). + // If it's false, the drag stops. + // Note that Drag will automatically compress MotionNotify events. + mousebind.Drag(X, win.Id, win.Id, "1", false, + func(X *xgbutil.XUtil, rx, ry, ex, ey int) (bool, xproto.Cursor) { + drawPencil(canvas, win, ex, ey) + return true, 0 + }, + func(X *xgbutil.XUtil, rx, ry, ex, ey int) { + drawPencil(canvas, win, ex, ey) + }, + func(X *xgbutil.XUtil, rx, ry, ex, ey int) {}) + + mousebind.Drag(X, win.Id, win.Id, "3", false, + func(X *xgbutil.XUtil, rx, ry, ex, ey int) (bool, xproto.Cursor) { + drawGopher(canvas, gopher, win, ex, ey) + return true, 0 + }, + func(X *xgbutil.XUtil, rx, ry, ex, ey int) { + drawGopher(canvas, gopher, win, ex, ey) + }, + func(X *xgbutil.XUtil, rx, ry, ex, ey int) {}) + + // Bind to the clear key specified, and just redraw the bg color. + keybind.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + clearCanvas(canvas, win) + }).Connect(X, win.Id, clearKey, false) + + // Bind a callback to each key specified in the 'pencils' color map. + // The response is to simply switch the pencil color. + for key, clr := range pencils { + c := clr + keybind.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + log.Printf("Changing pencil color to: %#v", c) + pencil = c + }).Connect(X, win.Id, key, false) + } + + // Output some basic directions. + fmt.Println("Use the left or right buttons on your mouse to paint " + + "squares and gophers.") + fmt.Println("Pressing numbers 1, 2, 3, 4, 5 or 6 will switch your pencil " + + "color.") + fmt.Println("Pressing 'c' will clear the canvas.") + + xevent.Main(X) +} + +// midRect takes an (x, y) position where the pointer was clicked, along with +// the width and height of the thing being drawn and the width and height of +// the canvas, and returns a Rectangle whose midpoint (roughly) is (x, y) and +// whose width and height match the parameters when the rectangle doesn't +// extend past the border of the canvas. Make sure to check if the rectange is +// empty or not before using it! +func midRect(x, y, width, height, canWidth, canHeight int) image.Rectangle { + return image.Rect( + max(0, min(canWidth, x-width/2)), // top left x + max(0, min(canHeight, y-height/2)), // top left y + max(0, min(canWidth, x+width/2)), // bottom right x + max(0, min(canHeight, y+height/2)), // bottom right y + ) +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vend/xgbutil/_examples/screenshot/main.go b/vend/xgbutil/_examples/screenshot/main.go new file mode 100644 index 0000000..5469d41 --- /dev/null +++ b/vend/xgbutil/_examples/screenshot/main.go @@ -0,0 +1,43 @@ +// Example screenshot shows how to take a screenshot of the current desktop +// and show it in a window. In a comment, it also shows how to save it as +// a png. +// +// It works by getting the image of the root window, which automatically +// includes all child windows. +package main + +import ( + "log" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Use the "NewDrawable" constructor to create an xgraphics.Image value + // from a drawable. (Usually this is done with pixmaps, but drawables + // can also be windows.) + ximg, err := xgraphics.NewDrawable(X, xproto.Drawable(X.RootWin())) + if err != nil { + log.Fatal(err) + } + + // Shows the screenshot in a window. + ximg.XShowExtra("Screenshot", true) + + // If you'd like to save it as a png, use: + // err = ximg.SavePng("screenshot.png") + // if err != nil { + // log.Fatal(err) + // } + + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/show-image/main.go b/vend/xgbutil/_examples/show-image/main.go new file mode 100644 index 0000000..a95b96d --- /dev/null +++ b/vend/xgbutil/_examples/show-image/main.go @@ -0,0 +1,42 @@ +// Example show-image is a very simple example to show how to use the +// xgraphics package to show an image in a window. +package main + +import ( + "bytes" + "image" + _ "image/png" + "log" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/gopher" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Read an example gopher image into a regular png image. + img, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng())) + if err != nil { + log.Fatal(err) + } + + // Now convert it into an X image. + ximg := xgraphics.NewConvert(X, img) + + // Now show it in a new window. + // We set the window title and tell the program to quit gracefully when + // the window is closed. + // There is also a convenience method, XShow, that requires no parameters. + ximg.XShowExtra("The Go Gopher!", true) + + // If we don't block, the program will end and the window will disappear. + // We could use a 'select{}' here, but xevent.Main will emit errors if + // something went wrong, so use that instead. + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/show-window-icons/main.go b/vend/xgbutil/_examples/show-window-icons/main.go new file mode 100644 index 0000000..1abdacb --- /dev/null +++ b/vend/xgbutil/_examples/show-window-icons/main.go @@ -0,0 +1,69 @@ +// Example show-window-icons shows how to get a list of all top-level client +// windows managed by the currently running window manager, and show the icon +// for each window. (Each icon is shown by opening its own window.) +package main + +import ( + "image/color" + "log" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" +) + +var ( + // The icon width and height to use. + // _NET_WM_ICON will be searched for an icon closest to these values. + // The icon closest in size to what's specified here will be used. + // The resulting icon will be scaled to this size. + // (Set both to 0 to avoid scaling and use the biggest possible icon.) + iconWidth, iconHeight = 300, 300 +) + +func main() { + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Get the list of window ids managed by the window manager. + clients, err := ewmh.ClientListGet(X) + if err != nil { + log.Fatal(err) + } + + // For each client, try to find its icon. If we find one, blend it with + // a nice background color and show it in its own window. + // Otherwise, skip it. + for _, wid := range clients { + // FindIcon will find an icon closest to the size specified. + // If one can't be found, the resulting image will be scaled + // automatically. + // To avoid scaling the icon, specify '0' for both the width and height. + // In this case, the largest icon found will be returned. + xicon, err := xgraphics.FindIcon(X, wid, iconWidth, iconHeight) + if err != nil { + log.Printf("Could not find icon for window %d.", wid) + continue + } + + // Get the name of this client. (It will be set as the icon window's + // name.) + name, err := ewmh.WmNameGet(X, wid) + if err != nil { // not a fatal error + log.Println(err) + name = "" + } + + // Blend a pink background color so its easy to see that alpha blending + // works. + xgraphics.BlendBgColor(xicon, color.RGBA{0xff, 0x0, 0xff, 0xff}) + xicon.XShowExtra(name, false) + } + + // All we really need to do is block, so a 'select{}' would be sufficient. + // But running the event loop will emit errors if anything went wrong. + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/simple-keybinding/main.go b/vend/xgbutil/_examples/simple-keybinding/main.go new file mode 100644 index 0000000..03e3f9d --- /dev/null +++ b/vend/xgbutil/_examples/simple-keybinding/main.go @@ -0,0 +1,82 @@ +// Example simple-keybinding shows how to grab keys on the root window and +// respond to them via callback functions. It also shows how to remove such +// callbacks so that they no longer respond to the key events. +// Note that more documentation can be found in the keybind package. +package main + +import ( + "log" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/xevent" +) + +func main() { + // Connect to the X server using the DISPLAY environment variable. + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Anytime the keybind (mousebind) package is used, keybind.Initialize + // *should* be called once. It isn't strictly necessary, but allows your + // keybindings to persist even if the keyboard mapping is changed during + // run-time. (Assuming you're using the xevent package's event loop.) + keybind.Initialize(X) + + // Before attaching callbacks, wrap them in a callback function type. + // The keybind package exposes two such callback types: keybind.KeyPressFun + // and keybind.KeyReleaseFun. + cb1 := keybind.KeyPressFun( + func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { + log.Println("Key press!") + }) + + // We can now attach the callback to a particular window and key + // combination. This particular example grabs a key on the root window, + // which makes it a global keybinding. + // Also, "Mod4-j" typically corresponds to pressing down the "Super" or + // "Windows" key on your keyboard, and then pressing the letter "j". + // N.B. This approach works by issuing a passive grab on the window + // specified. To respond to Key{Press,Release} events without a grab, use + // the xevent.Key{Press,Release}Fun callback function types instead. + err = cb1.Connect(X, X.RootWin(), "Mod4-j", true) + + // A keybinding can fail if the key string could not be parsed, or if you're + // trying to bind a key that has already been grabbed by another client. + if err != nil { + log.Fatal(err) + } + + // We can even attach multiple callbacks to the same key. + err = keybind.KeyPressFun( + func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { + log.Println("A second handler always happens after the first.") + }).Connect(X, X.RootWin(), "Mod4-j", true) + if err != nil { + log.Fatal(err) + } + + // Finally, if we want this client to stop responding to key events, we + // can attach another handler that, when run, detaches all previous + // handlers. + // This time, we'll show an example of a KeyRelease binding. + err = keybind.KeyReleaseFun( + func(X *xgbutil.XUtil, e xevent.KeyReleaseEvent) { + // Use keybind.Detach to detach the root window + // from all KeyPress *and* KeyRelease handlers. + keybind.Detach(X, X.RootWin()) + + log.Printf("Detached all Key{Press,Release}Events from the "+ + "root window (%d).", X.RootWin()) + }).Connect(X, X.RootWin(), "Mod4-Shift-q", true) + if err != nil { + log.Fatal(err) + } + + // Finally, start the main event loop. This will route any appropriate + // KeyPressEvents to your callback function. + log.Println("Program initialized. Start pressing keys!") + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/simple-mousebinding/main.go b/vend/xgbutil/_examples/simple-mousebinding/main.go new file mode 100644 index 0000000..534777d --- /dev/null +++ b/vend/xgbutil/_examples/simple-mousebinding/main.go @@ -0,0 +1,85 @@ +// Example simple-mousebinding shows how to grab buttons on the root window and +// respond to them via callback functions. It also shows how to remove such +// callbacks so that they no longer respond to the button events. +// Note that more documentation can be found in the mousebind package. +package main + +import ( + "log" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/mousebind" + "github.com/jezek/xgbutil/xevent" +) + +func main() { + // Connect to the X server using the DISPLAY environment variable. + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Anytime the mousebind (keybind) package is used, mousebind.Initialize + // *should* be called once. In the case of the mousebind package, this + // isn't strictly necessary, but the 'Drag' features of the mousebind + // package won't work without it. + mousebind.Initialize(X) + + // Before attaching callbacks, wrap them in a callback function type. + // The mouse package exposes two such callback types: + // mousebind.ButtonPressFun and mousebind.ButtonReleaseFun. + cb1 := mousebind.ButtonPressFun( + func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) { + log.Println("Button press!") + }) + + // We can now attach the callback to a particular window and button + // combination. This particular example grabs a button on the root window, + // which makes it a global mouse binding. + // Also, "Mod4-1" typically corresponds to pressing down the "Super" or + // "Windows" key on your keyboard, and then pressing the left mouse button. + // The last two parameters are whether to make a synchronous grab and + // whether to actually issue a grab, respectively. + // (The parameters used here are the common case.) + // See the documentation for the Connect method for more details. + err = cb1.Connect(X, X.RootWin(), "Mod4-1", false, true) + + // A mouse binding can fail if the mouse string could not be parsed, or if + // you're trying to bind a button that has already been grabbed by another + // client. + if err != nil { + log.Fatal(err) + } + + // We can even attach multiple callbacks to the same button. + err = mousebind.ButtonPressFun( + func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) { + log.Println("A second handler always happens after the first.") + }).Connect(X, X.RootWin(), "Mod4-1", false, true) + if err != nil { + log.Fatal(err) + } + + // Finally, if we want this client to stop responding to mouse events, we + // can attach another handler that, when run, detaches all previous + // handlers. + // This time, we'll show an example of a ButtonRelease binding. + err = mousebind.ButtonReleaseFun( + func(X *xgbutil.XUtil, e xevent.ButtonReleaseEvent) { + // Use mousebind.Detach to detach the root window + // from all ButtonPress *and* ButtonRelease handlers. + mousebind.Detach(X, X.RootWin()) + mousebind.Detach(X, X.RootWin()) + + log.Printf("Detached all Button{Press,Release}Events from the "+ + "root window (%d).", X.RootWin()) + }).Connect(X, X.RootWin(), "Mod4-Shift-1", false, true) + if err != nil { + log.Fatal(err) + } + + // Finally, start the main event loop. This will route any appropriate + // ButtonPressEvents to your callback function. + log.Println("Program initialized. Start pressing mouse buttons!") + xevent.Main(X) +} diff --git a/vend/xgbutil/_examples/window-gradient/main.go b/vend/xgbutil/_examples/window-gradient/main.go new file mode 100644 index 0000000..c919a04 --- /dev/null +++ b/vend/xgbutil/_examples/window-gradient/main.go @@ -0,0 +1,174 @@ +// Example window-gradient demonstrates how to create several windows and draw +// gradients as their background. Namely, it shows how to use the +// xgraphics.Image type as a canvas that can change size. This example also +// demonstrates how to compress ConfigureNotify events so that the gradient +// drawing does not lag behind the rate of incoming ConfigureNotify events. +package main + +import ( + "image" + "image/color" + "log" + "math/rand" + "time" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xgraphics" + "github.com/jezek/xgbutil/xwindow" +) + +func main() { + rand.Seed(time.Now().UnixNano()) + + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Create three gradient windows of varying size with random colors. + // Waiting a little bit inbetween seems to increase the diversity of the + // random colors. + + newGradientWindow(X, 200, 200, newRandomColor(), newRandomColor()) + + time.Sleep(500 * time.Millisecond) + newGradientWindow(X, 400, 400, newRandomColor(), newRandomColor()) + + time.Sleep(500 * time.Millisecond) + newGradientWindow(X, 600, 600, newRandomColor(), newRandomColor()) + + xevent.Main(X) +} + +// newGradientWindow creates a new X window, paints the initial gradient +// image, and listens for ConfigureNotify events. (A new gradient image must +// be painted in response to each ConfigureNotify event, since a +// ConfigureNotify event corresponds to a change in the window's geometry.) +func newGradientWindow(X *xgbutil.XUtil, width, height int, + start, end color.RGBA) { + + // Generate a new window id. + win, err := xwindow.Generate(X) + if err != nil { + log.Fatal(err) + } + + // Create the window and die if it fails. + err = win.CreateChecked(X.RootWin(), 0, 0, width, height, 0) + if err != nil { + log.Fatal(err) + } + + // In order to get ConfigureNotify events, we must listen to the window + // using the 'StructureNotify' mask. + win.Listen(xproto.EventMaskStructureNotify) + + // Paint the initial gradient to the window and then map the window. + paintGradient(X, win.Id, width, height, start, end) + win.Map() + + xevent.ConfigureNotifyFun( + func(X *xgbutil.XUtil, ev xevent.ConfigureNotifyEvent) { + // If the width and height have not changed, skip this one. + if int(ev.Width) == width && int(ev.Height) == height { + return + } + + // Compress ConfigureNotify events so that we don't lag when + // drawing gradients in response. + ev = compressConfigureNotify(X, ev) + + // Update the width and height and paint the gradient image. + width, height = int(ev.Width), int(ev.Height) + paintGradient(X, win.Id, width, height, start, end) + }).Connect(X, win.Id) +} + +// paintGradient creates a new xgraphics.Image value and draws a gradient +// starting at color 'start' and ending at color 'end'. +// +// Since xgraphics.Image values use pixmaps and pixmaps cannot be resized, +// a new pixmap must be allocated for each resize event. +func paintGradient(X *xgbutil.XUtil, wid xproto.Window, width, height int, + start, end color.RGBA) { + + ximg := xgraphics.New(X, image.Rect(0, 0, width, height)) + + // Now calculate the increment step between each RGB channel in + // the start and end colors. + rinc := (0xff * (int(end.R) - int(start.R))) / width + ginc := (0xff * (int(end.G) - int(start.G))) / width + binc := (0xff * (int(end.B) - int(start.B))) / width + + // Now apply the increment to each "column" in the image. + // Using 'ForExp' allows us to bypass the creation of a color.BGRA value + // for each pixel in the image. + ximg.ForExp(func(x, y int) (uint8, uint8, uint8, uint8) { + return uint8(int(start.B) + (binc*x)/0xff), + uint8(int(start.G) + (ginc*x)/0xff), + uint8(int(start.R) + (rinc*x)/0xff), + 0xff + }) + + // Set the surface to paint on for ximg. + // (This simply sets the background pixmap of the window to the pixmap + // used by ximg.) + ximg.XSurfaceSet(wid) + + // XDraw will draw the contents of ximg to its corresponding pixmap. + ximg.XDraw() + + // XPaint will "clear" the window provided so that it shows the updated + // pixmap. + ximg.XPaint(wid) + + // Since we will not reuse ximg, we must destroy its pixmap. + ximg.Destroy() +} + +// compressConfigureNotify "compresses" incoming ConfigureNotify events so that +// event processing never lags behind gradient drawing. +// This is necessary because drawing a gradient cannot keep up with the rate +// at which ConfigureNotify events are sent to us, thereby creating a "lag". +// Compression works by examining the "future" of the event queue, and skipping +// ahead to the most recent ConfigureNotify event and throwing away the rest. +// +// A more detailed treatment of event compression can be found in +// xgbutil/examples/compress-events. +func compressConfigureNotify(X *xgbutil.XUtil, + ev xevent.ConfigureNotifyEvent) xevent.ConfigureNotifyEvent { + + // Catch up with all X events as much as we can. + X.Sync() + xevent.Read(X, false) // non-blocking + + laste := ev + for i, ee := range xevent.Peek(X) { + if ee.Err != nil { + continue + } + if cn, ok := ee.Event.(xproto.ConfigureNotifyEvent); ok { + // Only compress this ConfigureNotify if it matches the window + // of the original event. + if ev.Event == cn.Event && ev.Window == cn.Window { + laste = xevent.ConfigureNotifyEvent{&cn} + defer func(i int) { xevent.DequeueAt(X, i) }(i) + } + } + } + return laste +} + +// newRandomColor creates a new RGBA color where each channel (except alpha) +// is randomly generated. +func newRandomColor() color.RGBA { + return color.RGBA{ + R: uint8(rand.Intn(256)), + G: uint8(rand.Intn(256)), + B: uint8(rand.Intn(256)), + A: 0xff, + } +} diff --git a/vend/xgbutil/_examples/window-name-sizes/main.go b/vend/xgbutil/_examples/window-name-sizes/main.go new file mode 100644 index 0000000..fbf782c --- /dev/null +++ b/vend/xgbutil/_examples/window-name-sizes/main.go @@ -0,0 +1,64 @@ +// Example window-names fetches a list of all top-level client windows managed +// by the currently running window manager, and prints the name and size +// of each window. +// +// This example demonstrates how to use some aspects of the ewmh and icccm +// packages. It also shows how to use the xwindow package to find the +// geometry of a client window. In particular, finding the geometry is +// intelligent, as it includes the geometry of the decorations if they exist. +package main + +import ( + "fmt" + "log" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/icccm" + "github.com/jezek/xgbutil/xwindow" +) + +func main() { + // Connect to the X server using the DISPLAY environment variable. + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Get a list of all client ids. + clientids, err := ewmh.ClientListGet(X) + if err != nil { + log.Fatal(err) + } + + // Iterate through each client, find its name and find its size. + for _, clientid := range clientids { + name, err := ewmh.WmNameGet(X, clientid) + + // If there was a problem getting _NET_WM_NAME or if its empty, + // try the old-school version. + if err != nil || len(name) == 0 { + name, err = icccm.WmNameGet(X, clientid) + + // If we still can't find anything, give up. + if err != nil || len(name) == 0 { + name = "N/A" + } + } + + // Now find the geometry, including decorations, of the client window. + // Note that DecorGeometry actually traverses the window tree by + // issuing QueryTree requests until a top-level window (i.e., its + // parent is the root window) is found. The geometry of *that* window + // is then returned. + dgeom, err := xwindow.New(X, clientid).DecorGeometry() + if err != nil { + log.Printf("Could not get geometry for %s (0x%X) because: %s", + name, clientid, err) + continue + } + + fmt.Printf("%s (0x%x)\n", name, clientid) + fmt.Printf("\tGeometry: %s\n", dgeom) + } +} diff --git a/vend/xgbutil/_examples/workarea-struts/main.go b/vend/xgbutil/_examples/workarea-struts/main.go new file mode 100644 index 0000000..d64db6b --- /dev/null +++ b/vend/xgbutil/_examples/workarea-struts/main.go @@ -0,0 +1,88 @@ +// Example workarea-struts shows how to find the all of the struts set by +// top-level clients and apply them to each active monitor to get the true +// workarea for each monitor. +// +// For example, consider a monitor with a 1920x1080 resolution and a panel +// on the bottom of the desktop 50 pixels tall. The actual workarea for the +// desktop then, is (0, 0) 1920x1030. (When there is more than one monitor, +// the x and y coordinates will be adjusted too.) +package main + +import ( + "fmt" + "log" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/xinerama" + "github.com/jezek/xgbutil/xrect" + "github.com/jezek/xgbutil/xwindow" +) + +func main() { + // Connect to the X server using the DISPLAY environment variable. + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Wrap the root window in a nice Window type. + root := xwindow.New(X, X.RootWin()) + + // Get the geometry of the root window. + rgeom, err := root.Geometry() + if err != nil { + log.Fatal(err) + } + + // Get the rectangles for each of the active physical heads. + // These are returned sorted in order from left to right and then top + // to bottom. + // But first check if Xinerama is enabled. If not, use root geometry. + var heads xinerama.Heads + if X.ExtInitialized("XINERAMA") { + heads, err = xinerama.PhysicalHeads(X) + if err != nil { + log.Fatal(err) + } + } else { + heads = xinerama.Heads{rgeom} + } + + // Fetch the list of top-level client window ids currently managed + // by the running window manager. + clients, err := ewmh.ClientListGet(X) + if err != nil { + log.Fatal(err) + } + + // Output the head geometry before modifying them. + fmt.Println("Workarea for each head:") + for i, head := range heads { + fmt.Printf("\tHead #%d: %s\n", i+1, head) + } + + // For each client, check to see if it has struts, and if so, apply + // them to our list of head rectangles. + for _, clientid := range clients { + strut, err := ewmh.WmStrutPartialGet(X, clientid) + if err != nil { // no struts for this client + continue + } + + // Apply the struts to our heads. + // This modifies 'heads' in place. + xrect.ApplyStrut(heads, uint(rgeom.Width()), uint(rgeom.Height()), + strut.Left, strut.Right, strut.Top, strut.Bottom, + strut.LeftStartY, strut.LeftEndY, + strut.RightStartY, strut.RightEndY, + strut.TopStartX, strut.TopEndX, + strut.BottomStartX, strut.BottomEndX) + } + + // Now output the head geometry again after modification. + fmt.Println("Workarea for each head after applying struts:") + for i, head := range heads { + fmt.Printf("\tHead #%d: %s\n", i+1, head) + } +} diff --git a/vend/xgbutil/_examples/xgraphics-compat/main.go b/vend/xgbutil/_examples/xgraphics-compat/main.go new file mode 100644 index 0000000..ac75bcd --- /dev/null +++ b/vend/xgbutil/_examples/xgraphics-compat/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "log" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xgraphics" +) + +func main() { + log.SetFlags(0) + + X, err := xgbutil.NewConn() + if err != nil { + log.Fatalln(err) + } + checkCompatibility(X) +} + +// checkCompatibility reads info in the X setup info struct and emits +// messages to stderr if they don't correspond to values that xgraphics +// supports. +// The idea is that in the future, we'll support more values. +// The real reason for checkCompatibility is to make debugging easier. Without +// it, if the values weren't what we'd expect, we'd see garbled images in the +// best case, and probably BadLength errors in the worst case. +func checkCompatibility(X *xgbutil.XUtil) { + s := X.Setup() + scrn := X.Screen() + failed := false + + if s.ImageByteOrder != xproto.ImageOrderLSBFirst { + log.Printf("Your X server uses MSB image byte order. Unfortunately, " + + "xgraphics currently requires LSB image byte order. You may see " + + "weird things. Please report this.") + failed = true + } + if s.BitmapFormatBitOrder != xproto.ImageOrderLSBFirst { + log.Printf("Your X server uses MSB bitmap bit order. Unfortunately, " + + "xgraphics currently requires LSB bitmap bit order. If you " + + "aren't using X bitmaps, you should be able to proceed normally. " + + "Please report this.") + failed = true + } + if s.BitmapFormatScanlineUnit != 32 { + log.Printf("xgraphics expects that the scanline unit is set to 32, "+ + "but your X server has it set to '%d'. "+ + "Namely, xgraphics hasn't been tested on other values. Things "+ + "may still work. Particularly, if you aren't using X bitmaps, "+ + "you should be completely unaffected. Please report this.", + s.BitmapFormatScanlineUnit) + failed = true + } + if scrn.RootDepth != 24 { + log.Printf("xgraphics expects that the root window has a depth of 24, "+ + "but yours has depth '%d'. Its possible things will still work "+ + "if your value is 32, but will be unlikely to work with values "+ + "less than 24. Please report this.", scrn.RootDepth) + failed = true + } + + // Look for the default format for pixmaps and make sure bits per pixel + // is 32. + format := xgraphics.GetFormat(X, scrn.RootDepth) + if format.BitsPerPixel != 32 { + log.Printf("xgraphics expects that the bits per pixel for the root "+ + "window depth is 32. On your system, the root depth is %d and "+ + "the bits per pixel is %d. Things will most certainly not work. "+ + "Please report this.", + scrn.RootDepth, format.BitsPerPixel) + failed = true + } + + // Give instructions on reporting the issue. + if failed { + log.Printf("Please report the aforementioned error message(s) at " + + "https://github.com/jezek/xgbutil. Please also include the " + + "entire output of the `xdpyinfo` command in your report. Thanks!") + } else { + log.Printf("No compatibility issues detected.") + } +} diff --git a/vend/xgbutil/_examples/xmodmap/main.go b/vend/xgbutil/_examples/xmodmap/main.go new file mode 100644 index 0000000..651436f --- /dev/null +++ b/vend/xgbutil/_examples/xmodmap/main.go @@ -0,0 +1,92 @@ +// Example xmodmap shows how one might implement a rudimentary version +// of xmodmap's modifier listing. +// (xmodmap is a program that shows all modifier keys, and which +// keysyms activate each modifier. xmodmap can also modify the modifier +// mapping, which this doesn't do.) +package main + +import ( + "fmt" + "log" + "strings" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/keybind" +) + +func main() { + // Connect to the X server using the DISPLAY environment variable. + X, err := xgbutil.NewConn() + if err != nil { + log.Fatal(err) + } + + // Nice names for the modifier keys (same ones used by xmodmap). + // This slice corresponds to the keybind.Modifiers slice (except for + // the last 'Any' modifier element). + nice := []string{ + "shift", "lock", "control", "mod1", "mod2", "mod3", "mod4", "mod5", + } + + // Whenever one uses the keybind package, Initialize should always be + // called first. In this case, it initializes the key and modifier maps. + keybind.Initialize(X) + + // Get the current modifier map. + // The map is actually a table, where rows correspond to modifiers, and + // columns correspond to the keys that activate that modifier. + modMap := keybind.ModMapGet(X) + + // The number of keycodes allowed per modifier (i.e., the number of + // columns in the modifier map). + kPerMod := int(modMap.KeycodesPerModifier) + + // Get the number of allowable keysyms per keycode. + // This is used to search for a valid keysym for a particular keycode. + symsPerKc := int(keybind.KeyMapGet(X).KeysymsPerKeycode) + + // Imitate everything... + fmt.Printf("xmodmap: up to %d keys per modifier, "+ + "(keycodes in parentheses):\n\n", kPerMod) + + // Iterate through all keyboard modifiers defined in xgb/xproto + // except the 'Any' modifier (which is last). + for mmi := range keybind.Modifiers[:len(keybind.Modifiers)-1] { + niceName := nice[mmi] + keys := make([]string, 0, kPerMod) + + // row is the row for the 'mmi' modifier in the modifier mapping table. + row := mmi * kPerMod + + // Iterate over each keycode in the modifier map for this modifier. + for _, kc := range modMap.Keycodes[row : row+kPerMod] { + // If this entry doesn't have a keycode (i.e., it's zero), we + // have to skip it. + if kc == 0 { + continue + } + + // Look for the first valid keysym in the keyboard map corresponding + // to this keycode. If one can't be found, output "BadKey." + var ksym xproto.Keysym = 0 + for column := 0; column < symsPerKc; column++ { + ksym = keybind.KeysymGet(X, kc, byte(column)) + if ksym != 0 { + break + } + } + + if ksym == 0 { + keys = append(keys, fmt.Sprintf("BadKey (0x%x)", kc)) + } else { + keys = append(keys, + fmt.Sprintf("%s (0x%x)", keybind.KeysymToStr(ksym), kc)) + } + } + + fmt.Printf("%-12s%s\n", niceName, strings.Join(keys, ", ")) + } + fmt.Println("") +} diff --git a/vend/xgbutil/doc.go b/vend/xgbutil/doc.go new file mode 100644 index 0000000..39aa1b5 --- /dev/null +++ b/vend/xgbutil/doc.go @@ -0,0 +1,67 @@ +/* +Package xgbutil is a utility library designed to make common tasks with the X +server easier. The central design choice that has driven development is to hide +the complexity of X wherever possible but expose it when necessary. + +For example, the xevent package provides an implementation of an X event loop +that acts as a dispatcher to event handlers set up with the xevent, keybind and +mousebind packages. At the same time, the event queue is exposed and can be +modified using xevent.Peek and xevent.DequeueAt. + +Sub-packages + +The xgbutil package is considerably small, and only contains some type +definitions and the initial setup for an X connection. Much of the +functionality of xgbutil comes from its sub-packages. Each sub-package is +appropriately documented. + +Installation + +xgbutil is go-gettable: + + go get github.com/jezek/xgbutil + +Dependencies + +XGB is the main dependency, and is required for all packages inside xgbutil. + +graphics-go and freetype-go are also required if using the xgraphics package. + +Quick Example + +A quick example to demonstrate that xgbutil is working correctly: + + go get github.com/jezek/xgbutil/examples/window-name-sizes + GO/PATH/bin/window-name-sizes + +The output will be a list of names of all top-level windows and their geometry +including window manager decorations. (Assuming your window manager supports +some basic EWMH properties.) + +Examples + +The examples directory contains a sizable number of examples demonstrating +common tasks with X. They are intended to demonstrate a single thing each, +although a few that require setup are necessarily long. Each example is +heavily documented. + +The examples directory should be your first stop when learning how to use +xgbutil. + +xgbutil is also used heavily throughout my (BurntSushi) window manager, Wingo. It may be +useful reference material. + +Wingo project page: https://github.com/BurntSushi/wingo + +Thread Safety + +While I am (BurntSushi) fairly confident that XGB is thread safe, I am only somewhat +confident that xgbutil is thread safe. It simply has not been tested enough for +my confidence to be higher. + +Note that the xevent package's X event loop is not concurrent. Namely, +designing a generally concurrent X event loop is extremely complex. Instead, +the onus is on you, the user, to design concurrent callback functions if +concurrency is desired. +*/ +package xgbutil diff --git a/vend/xgbutil/ewmh/doc.go b/vend/xgbutil/ewmh/doc.go new file mode 100644 index 0000000..6e7506a --- /dev/null +++ b/vend/xgbutil/ewmh/doc.go @@ -0,0 +1,56 @@ +/* +Package ewmh provides a comprehensive API to get and set properties specified +by the EWMH spec, as well as perform actions specified by the EWMH spec. + +Since there are so many functions and they adhere to an existing spec, +this package file does not contain much documentation. Indeed, each +method has only a single comment associated with it: the EWMH property name. + +The idea is to +provide a consistent interface to use all facilities described in the EWMH +spec: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html. + +Naming scheme + +Using "_NET_ACTIVE_WINDOW" as an example, +functions "ActiveWindowGet" and "ActiveWindowSet" get and set the +property, respectively. Both of these functions exist for most EWMH +properties. Additionally, some EWMH properties support sending a client +message event to request the window manager to perform some action. In the +case of "_NET_ACTIVE_WINDOW", this request is used to set the active +window. + +These sorts of functions end in "Req". So for "_NET_ACTIVE_WINDOW", +the method name is "ActiveWindowReq". Moreover, most requests include +various parameters that don't need to be changed often (like the source +indication). Thus, by default, functions ending in "Req" force these to +sensible defaults. If you need access to all of the parameters, use the +corresponding "ReqExtra" method. So for "_NET_ACTIVE_WINDOW", that would +be "ActiveWindowReqExtra". (If no "ReqExtra" method exists, then the +"Req" method covers all available parameters.) + +This naming scheme has one exception: if a property's only use is through +sending an event (like "_NET_CLOSE_WINDOW"), then the name will be +"CloseWindow" for the short-hand version and "CloseWindowExtra" +for access to all of the parameters. (Since there is no "_NET_CLOSE_WINDOW" +property, there is no need for "CloseWindowGet" and "CloseWindowSet" +functions.) + +For properties that store more than just a simple integer, name or list +of integers, structs have been created and exposed to organize the +information returned in a sensible manner. For example, the +"_NET_DESKTOP_GEOMETRY" property would typically return a slice of integers +of length 2, where the first integer is the width and the second is the +height. Xgbutil will wrap this in a struct with the obvious members. These +structs are documented. + +Finally, functions ending in "*Set" are typically only used when setting +properties on clients *you've* created or when the window manager sets +properties. Thus, it's unlikely that you should use them unless you're +creating a top-level client or building a window manager. + +Functions ending in "Get" or "Req[Extra]" are commonly used. + +N.B. Not all properties have "*Req" functions. +*/ +package ewmh diff --git a/vend/xgbutil/ewmh/ewmh.go b/vend/xgbutil/ewmh/ewmh.go new file mode 100644 index 0000000..623f2e0 --- /dev/null +++ b/vend/xgbutil/ewmh/ewmh.go @@ -0,0 +1,1159 @@ +package ewmh + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xprop" +) + +// ClientEvent is a convenience function that sends ClientMessage events +// to the root window as specified by the EWMH spec. +func ClientEvent(xu *xgbutil.XUtil, window xproto.Window, messageType string, + data ...interface{}) error { + + mstype, err := xprop.Atm(xu, messageType) + if err != nil { + return err + } + + evMask := (xproto.EventMaskSubstructureNotify | + xproto.EventMaskSubstructureRedirect) + cm, err := xevent.NewClientMessage(32, window, mstype, data...) + if err != nil { + return err + } + + return xevent.SendRootEvent(xu, cm, uint32(evMask)) +} + +// _NET_ACTIVE_WINDOW get +func ActiveWindowGet(xu *xgbutil.XUtil) (xproto.Window, error) { + return xprop.PropValWindow(xprop.GetProperty(xu, xu.RootWin(), + "_NET_ACTIVE_WINDOW")) +} + +// _NET_ACTIVE_WINDOW set +func ActiveWindowSet(xu *xgbutil.XUtil, win xproto.Window) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_ACTIVE_WINDOW", "WINDOW", + uint(win)) +} + +// _NET_ACTIVE_WINDOW req +func ActiveWindowReq(xu *xgbutil.XUtil, win xproto.Window) error { + return ActiveWindowReqExtra(xu, win, 2, 0, 0) +} + +// _NET_ACTIVE_WINDOW req extra +func ActiveWindowReqExtra(xu *xgbutil.XUtil, win xproto.Window, source int, + time xproto.Timestamp, currentActive xproto.Window) error { + + return ClientEvent(xu, win, "_NET_ACTIVE_WINDOW", source, int(time), + int(currentActive)) +} + +// _NET_CLIENT_LIST get +func ClientListGet(xu *xgbutil.XUtil) ([]xproto.Window, error) { + return xprop.PropValWindows(xprop.GetProperty(xu, xu.RootWin(), + "_NET_CLIENT_LIST")) +} + +// _NET_CLIENT_LIST set +func ClientListSet(xu *xgbutil.XUtil, wins []xproto.Window) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_CLIENT_LIST", "WINDOW", + xprop.WindowToInt(wins)...) +} + +// _NET_CLIENT_LIST_STACKING get +func ClientListStackingGet(xu *xgbutil.XUtil) ([]xproto.Window, error) { + return xprop.PropValWindows(xprop.GetProperty(xu, xu.RootWin(), + "_NET_CLIENT_LIST_STACKING")) +} + +// _NET_CLIENT_LIST_STACKING set +func ClientListStackingSet(xu *xgbutil.XUtil, wins []xproto.Window) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_CLIENT_LIST_STACKING", + "WINDOW", xprop.WindowToInt(wins)...) +} + +// _NET_CLOSE_WINDOW req +func CloseWindow(xu *xgbutil.XUtil, win xproto.Window) error { + return CloseWindowExtra(xu, win, 0, 2) +} + +// _NET_CLOSE_WINDOW req extra +func CloseWindowExtra(xu *xgbutil.XUtil, win xproto.Window, + time xproto.Timestamp, source int) error { + + return ClientEvent(xu, win, "_NET_CLOSE_WINDOW", int(time), source) +} + +// _NET_CURRENT_DESKTOP get +func CurrentDesktopGet(xu *xgbutil.XUtil) (uint, error) { + return xprop.PropValNum(xprop.GetProperty(xu, xu.RootWin(), + "_NET_CURRENT_DESKTOP")) +} + +// _NET_CURRENT_DESKTOP set +func CurrentDesktopSet(xu *xgbutil.XUtil, desk uint) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_CURRENT_DESKTOP", + "CARDINAL", desk) +} + +// _NET_CURRENT_DESKTOP req +func CurrentDesktopReq(xu *xgbutil.XUtil, desk int) error { + return CurrentDesktopReqExtra(xu, desk, 0) +} + +// _NET_CURRENT_DESKTOP req extra +func CurrentDesktopReqExtra(xu *xgbutil.XUtil, desk int, + time xproto.Timestamp) error { + + return ClientEvent(xu, xu.RootWin(), "_NET_CURRENT_DESKTOP", desk, + int(time)) +} + +// _NET_DESKTOP_NAMES get +func DesktopNamesGet(xu *xgbutil.XUtil) ([]string, error) { + return xprop.PropValStrs(xprop.GetProperty(xu, xu.RootWin(), + "_NET_DESKTOP_NAMES")) +} + +// _NET_DESKTOP_NAMES set +func DesktopNamesSet(xu *xgbutil.XUtil, names []string) error { + nullterm := make([]byte, 0) + for _, name := range names { + nullterm = append(nullterm, name...) + nullterm = append(nullterm, 0) + } + return xprop.ChangeProp(xu, xu.RootWin(), 8, "_NET_DESKTOP_NAMES", + "UTF8_STRING", nullterm) +} + +// DesktopGeometry is a struct that houses the width and height of a +// _NET_DESKTOP_GEOMETRY property reply. +type DesktopGeometry struct { + Width int + Height int +} + +// _NET_DESKTOP_GEOMETRY get +func DesktopGeometryGet(xu *xgbutil.XUtil) (*DesktopGeometry, error) { + geom, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), + "_NET_DESKTOP_GEOMETRY")) + if err != nil { + return nil, err + } + + return &DesktopGeometry{Width: int(geom[0]), Height: int(geom[1])}, nil +} + +// _NET_DESKTOP_GEOMETRY set +func DesktopGeometrySet(xu *xgbutil.XUtil, dg *DesktopGeometry) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_GEOMETRY", + "CARDINAL", uint(dg.Width), uint(dg.Height)) +} + +// _NET_DESKTOP_GEOMETRY req +func DesktopGeometryReq(xu *xgbutil.XUtil, dg *DesktopGeometry) error { + return ClientEvent(xu, xu.RootWin(), "_NET_DESKTOP_GEOMETRY", dg.Width, + dg.Height) +} + +// DesktopLayout is a struct that organizes information pertaining to +// the _NET_DESKTOP_LAYOUT property. Namely, the orientation, the number +// of columns, the number of rows, and the starting corner. +type DesktopLayout struct { + Orientation int + Columns int + Rows int + StartingCorner int +} + +// _NET_DESKTOP_LAYOUT constants for orientation +const ( + OrientHorz = iota + OrientVert +) + +// _NET_DESKTOP_LAYOUT constants for starting corner +const ( + TopLeft = iota + TopRight + BottomRight + BottomLeft +) + +// _NET_DESKTOP_LAYOUT get +func DesktopLayoutGet(xu *xgbutil.XUtil) (dl *DesktopLayout, err error) { + dlraw, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), + "_NET_DESKTOP_LAYOUT")) + if err != nil { + return nil, err + } + + dl = &DesktopLayout{} + dl.Orientation = int(dlraw[0]) + dl.Columns = int(dlraw[1]) + dl.Rows = int(dlraw[2]) + + if len(dlraw) > 3 { + dl.StartingCorner = int(dlraw[3]) + } else { + dl.StartingCorner = TopLeft + } + + return dl, nil +} + +// _NET_DESKTOP_LAYOUT set +func DesktopLayoutSet(xu *xgbutil.XUtil, orientation, columns, rows, + startingCorner uint) error { + + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_LAYOUT", + "CARDINAL", orientation, columns, rows, + startingCorner) +} + +// DesktopViewport is a struct that contains a pairing of x,y coordinates +// representing the top-left corner of each desktop. (There will typically +// be one struct here for each desktop in existence.) +type DesktopViewport struct { + X int + Y int +} + +// _NET_DESKTOP_VIEWPORT get +func DesktopViewportGet(xu *xgbutil.XUtil) ([]DesktopViewport, error) { + coords, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), + "_NET_DESKTOP_VIEWPORT")) + if err != nil { + return nil, err + } + + viewports := make([]DesktopViewport, len(coords)/2) + for i, _ := range viewports { + viewports[i] = DesktopViewport{ + X: int(coords[i*2]), + Y: int(coords[i*2+1]), + } + } + return viewports, nil +} + +// _NET_DESKTOP_VIEWPORT set +func DesktopViewportSet(xu *xgbutil.XUtil, viewports []DesktopViewport) error { + coords := make([]uint, len(viewports)*2) + for i, viewport := range viewports { + coords[i*2] = uint(viewport.X) + coords[i*2+1] = uint(viewport.Y) + } + + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_VIEWPORT", + "CARDINAL", coords...) +} + +// _NET_DESKTOP_VIEWPORT req +func DesktopViewportReq(xu *xgbutil.XUtil, x, y int) error { + return ClientEvent(xu, xu.RootWin(), "_NET_DESKTOP_VIEWPORT", x, y) +} + +// FrameExtents is a struct that organizes information associated with +// the _NET_FRAME_EXTENTS property. Namely, the left, right, top and bottom +// decoration sizes. +type FrameExtents struct { + Left int + Right int + Top int + Bottom int +} + +// _NET_FRAME_EXTENTS get +func FrameExtentsGet(xu *xgbutil.XUtil, + win xproto.Window) (*FrameExtents, error) { + + raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "_NET_FRAME_EXTENTS")) + if err != nil { + return nil, err + } + + return &FrameExtents{ + Left: int(raw[0]), + Right: int(raw[1]), + Top: int(raw[2]), + Bottom: int(raw[3]), + }, nil +} + +// _NET_FRAME_EXTENTS set +func FrameExtentsSet(xu *xgbutil.XUtil, win xproto.Window, + extents *FrameExtents) error { + raw := make([]uint, 4) + raw[0] = uint(extents.Left) + raw[1] = uint(extents.Right) + raw[2] = uint(extents.Top) + raw[3] = uint(extents.Bottom) + + return xprop.ChangeProp32(xu, win, "_NET_FRAME_EXTENTS", "CARDINAL", raw...) +} + +// _NET_MOVERESIZE_WINDOW req +// If 'w' or 'h' are 0, then they are not sent. +// If you need to resize a window without moving it, use the ReqExtra variant, +// or Resize. +func MoveresizeWindow(xu *xgbutil.XUtil, win xproto.Window, + x, y, w, h int) error { + + return MoveresizeWindowExtra(xu, win, x, y, w, h, xproto.GravityBitForget, + 2, true, true) +} + +// _NET_MOVERESIZE_WINDOW req resize only +func ResizeWindow(xu *xgbutil.XUtil, win xproto.Window, w, h int) error { + return MoveresizeWindowExtra(xu, win, 0, 0, w, h, xproto.GravityBitForget, + 2, false, false) +} + +// _NET_MOVERESIZE_WINDOW req move only +func MoveWindow(xu *xgbutil.XUtil, win xproto.Window, x, y int) error { + return MoveresizeWindowExtra(xu, win, x, y, 0, 0, xproto.GravityBitForget, + 2, true, true) +} + +// _NET_MOVERESIZE_WINDOW req extra +// If 'w' or 'h' are 0, then they are not sent. +// To not set 'x' or 'y', 'usex' or 'usey' need to be set to false. +func MoveresizeWindowExtra(xu *xgbutil.XUtil, win xproto.Window, x, y, w, h, + gravity, source int, usex, usey bool) error { + + flags := gravity + flags |= source << 12 + if usex { + flags |= 1 << 8 + } + if usey { + flags |= 1 << 9 + } + if w > 0 { + flags |= 1 << 10 + } + if h > 0 { + flags |= 1 << 11 + } + + return ClientEvent(xu, win, "_NET_MOVERESIZE_WINDOW", flags, x, y, w, h) +} + +// _NET_NUMBER_OF_DESKTOPS get +func NumberOfDesktopsGet(xu *xgbutil.XUtil) (uint, error) { + return xprop.PropValNum(xprop.GetProperty(xu, xu.RootWin(), + "_NET_NUMBER_OF_DESKTOPS")) +} + +// _NET_NUMBER_OF_DESKTOPS set +func NumberOfDesktopsSet(xu *xgbutil.XUtil, numDesks uint) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_NUMBER_OF_DESKTOPS", + "CARDINAL", numDesks) +} + +// _NET_NUMBER_OF_DESKTOPS req +func NumberOfDesktopsReq(xu *xgbutil.XUtil, numDesks int) error { + return ClientEvent(xu, xu.RootWin(), "_NET_NUMBER_OF_DESKTOPS", numDesks) +} + +// _NET_REQUEST_FRAME_EXTENTS req +func RequestFrameExtents(xu *xgbutil.XUtil, win xproto.Window) error { + return ClientEvent(xu, win, "_NET_REQUEST_FRAME_EXTENTS") +} + +// _NET_RESTACK_WINDOW req +// The shortcut here is to just raise the window to the top of the window stack. +func RestackWindow(xu *xgbutil.XUtil, win xproto.Window) error { + return RestackWindowExtra(xu, win, xproto.StackModeAbove, 0, 2) +} + +// _NET_RESTACK_WINDOW req extra +func RestackWindowExtra(xu *xgbutil.XUtil, win xproto.Window, stackMode int, + sibling xproto.Window, source int) error { + + return ClientEvent(xu, win, "_NET_RESTACK_WINDOW", source, int(sibling), + stackMode) +} + +// _NET_SHOWING_DESKTOP get +func ShowingDesktopGet(xu *xgbutil.XUtil) (bool, error) { + reply, err := xprop.GetProperty(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP") + if err != nil { + return false, err + } + + val, err := xprop.PropValNum(reply, nil) + if err != nil { + return false, err + } + + return val == 1, nil +} + +// _NET_SHOWING_DESKTOP set +func ShowingDesktopSet(xu *xgbutil.XUtil, show bool) error { + var showInt uint + if show { + showInt = 1 + } else { + showInt = 0 + } + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP", + "CARDINAL", showInt) +} + +// _NET_SHOWING_DESKTOP req +func ShowingDesktopReq(xu *xgbutil.XUtil, show bool) error { + var showInt uint + if show { + showInt = 1 + } else { + showInt = 0 + } + return ClientEvent(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP", showInt) +} + +// _NET_SUPPORTED get +func SupportedGet(xu *xgbutil.XUtil) ([]string, error) { + reply, err := xprop.GetProperty(xu, xu.RootWin(), "_NET_SUPPORTED") + return xprop.PropValAtoms(xu, reply, err) +} + +// _NET_SUPPORTED set +// This will create any atoms in the argument if they don't already exist. +func SupportedSet(xu *xgbutil.XUtil, atomNames []string) error { + atoms, err := xprop.StrToAtoms(xu, atomNames) + if err != nil { + return err + } + + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_SUPPORTED", "ATOM", + atoms...) +} + +// _NET_SUPPORTING_WM_CHECK get +func SupportingWmCheckGet(xu *xgbutil.XUtil, + win xproto.Window) (xproto.Window, error) { + + return xprop.PropValWindow(xprop.GetProperty(xu, win, + "_NET_SUPPORTING_WM_CHECK")) +} + +// _NET_SUPPORTING_WM_CHECK set +func SupportingWmCheckSet(xu *xgbutil.XUtil, win xproto.Window, + wmWin xproto.Window) error { + + return xprop.ChangeProp32(xu, win, "_NET_SUPPORTING_WM_CHECK", "WINDOW", + uint(wmWin)) +} + +// _NET_VIRTUAL_ROOTS get +func VirtualRootsGet(xu *xgbutil.XUtil) ([]xproto.Window, error) { + return xprop.PropValWindows(xprop.GetProperty(xu, xu.RootWin(), + "_NET_VIRTUAL_ROOTS")) +} + +// _NET_VIRTUAL_ROOTS set +func VirtualRootsSet(xu *xgbutil.XUtil, wins []xproto.Window) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_VIRTUAL_ROOTS", "WINDOW", + xprop.WindowToInt(wins)...) +} + +// _NET_VISIBLE_DESKTOPS get +// This is not part of the EWMH spec, but is a property of my own creation. +// It allows the window manager to report that it has multiple desktops +// viewable at the same time. (This conflicts with other EWMH properties, +// so I don't think this will ever be added to the official spec.) +func VisibleDesktopsGet(xu *xgbutil.XUtil) ([]uint, error) { + return xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), + "_NET_VISIBLE_DESKTOPS")) +} + +// _NET_VISIBLE_DESKTOPS set +func VisibleDesktopsSet(xu *xgbutil.XUtil, desktops []uint) error { + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_VISIBLE_DESKTOPS", + "CARDINAL", desktops...) +} + +// _NET_WM_ALLOWED_ACTIONS get +func WmAllowedActionsGet(xu *xgbutil.XUtil, + win xproto.Window) ([]string, error) { + + raw, err := xprop.GetProperty(xu, win, "_NET_WM_ALLOWED_ACTIONS") + return xprop.PropValAtoms(xu, raw, err) +} + +// _NET_WM_ALLOWED_ACTIONS set +func WmAllowedActionsSet(xu *xgbutil.XUtil, win xproto.Window, + atomNames []string) error { + + atoms, err := xprop.StrToAtoms(xu, atomNames) + if err != nil { + return err + } + + return xprop.ChangeProp32(xu, win, "_NET_WM_ALLOWED_ACTIONS", "ATOM", + atoms...) +} + +// _NET_WM_DESKTOP get +func WmDesktopGet(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { + return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_DESKTOP")) +} + +// _NET_WM_DESKTOP set +func WmDesktopSet(xu *xgbutil.XUtil, win xproto.Window, desk uint) error { + return xprop.ChangeProp32(xu, win, "_NET_WM_DESKTOP", "CARDINAL", + uint(desk)) +} + +// _NET_WM_DESKTOP req +func WmDesktopReq(xu *xgbutil.XUtil, win xproto.Window, desk uint) error { + return WmDesktopReqExtra(xu, win, desk, 2) +} + +// _NET_WM_DESKTOP req extra +func WmDesktopReqExtra(xu *xgbutil.XUtil, win xproto.Window, desk uint, + source int) error { + + return ClientEvent(xu, win, "_NET_WM_DESKTOP", desk, source) +} + +// WmFullscreenMonitors is a struct that organizes information related to the +// _NET_WM_FULLSCREEN_MONITORS property. Namely, the top, bottom, left and +// right monitor edges for a particular window. +type WmFullscreenMonitors struct { + Top uint + Bottom uint + Left uint + Right uint +} + +// _NET_WM_FULLSCREEN_MONITORS get +func WmFullscreenMonitorsGet(xu *xgbutil.XUtil, + win xproto.Window) (*WmFullscreenMonitors, error) { + + raw, err := xprop.PropValNums( + xprop.GetProperty(xu, win, "_NET_WM_FULLSCREEN_MONITORS")) + if err != nil { + return nil, err + } + + return &WmFullscreenMonitors{ + Top: raw[0], + Bottom: raw[1], + Left: raw[2], + Right: raw[3], + }, nil +} + +// _NET_WM_FULLSCREEN_MONITORS set +func WmFullscreenMonitorsSet(xu *xgbutil.XUtil, win xproto.Window, + edges *WmFullscreenMonitors) error { + + raw := make([]uint, 4) + raw[0] = edges.Top + raw[1] = edges.Bottom + raw[2] = edges.Left + raw[3] = edges.Right + + return xprop.ChangeProp32(xu, win, "_NET_WM_FULLSCREEN_MONITORS", + "CARDINAL", raw...) +} + +// _NET_WM_FULLSCREEN_MONITORS req +func WmFullscreenMonitorsReq(xu *xgbutil.XUtil, win xproto.Window, + edges *WmFullscreenMonitors) error { + + return WmFullscreenMonitorsReqExtra(xu, win, edges, 2) +} + +// _NET_WM_FULLSCREEN_MONITORS req extra +func WmFullscreenMonitorsReqExtra(xu *xgbutil.XUtil, win xproto.Window, + edges *WmFullscreenMonitors, source int) error { + + return ClientEvent(xu, win, "_NET_WM_FULLSCREEN_MONITORS", + edges.Top, edges.Bottom, edges.Left, edges.Right, source) +} + +// _NET_WM_HANDLED_ICONS get +func WmHandledIconsGet(xu *xgbutil.XUtil, win xproto.Window) (bool, error) { + reply, err := xprop.GetProperty(xu, win, "_NET_WM_HANDLED_ICONS") + if err != nil { + return false, err + } + + val, err := xprop.PropValNum(reply, nil) + if err != nil { + return false, err + } + + return val == 1, nil +} + +// _NET_WM_HANDLED_ICONS set +func WmHandledIconsSet(xu *xgbutil.XUtil, handle bool) error { + var handled uint + if handle { + handled = 1 + } else { + handled = 0 + } + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_WM_HANDLED_ICONS", + "CARDINAL", handled) +} + +// WmIcon is a struct that contains data for a single icon. +// The WmIcon method will return a list of these, since a single +// client can specify multiple icons of varying sizes. +type WmIcon struct { + Width uint + Height uint + Data []uint +} + +// _NET_WM_ICON get +func WmIconGet(xu *xgbutil.XUtil, win xproto.Window) ([]WmIcon, error) { + icon, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_WM_ICON")) + if err != nil { + return nil, err + } + + wmicons := make([]WmIcon, 0) + start := uint(0) + for int(start) < len(icon) { + w, h := icon[start], icon[start+1] + upto := w * h + + wmicon := WmIcon{ + Width: w, + Height: h, + Data: icon[(start + 2):(start + upto + 2)], + } + wmicons = append(wmicons, wmicon) + + start += upto + 2 + } + + return wmicons, nil +} + +// _NET_WM_ICON set +func WmIconSet(xu *xgbutil.XUtil, win xproto.Window, icons []WmIcon) error { + raw := make([]uint, 0, 10000) // start big + for _, icon := range icons { + raw = append(raw, icon.Width, icon.Height) + raw = append(raw, icon.Data...) + } + + return xprop.ChangeProp32(xu, win, "_NET_WM_ICON", "CARDINAL", raw...) +} + +// WmIconGeometry struct organizes the information pertaining to the +// _NET_WM_ICON_GEOMETRY property. Namely, x, y, width and height. +type WmIconGeometry struct { + X int + Y int + Width uint + Height uint +} + +// _NET_WM_ICON_GEOMETRY get +func WmIconGeometryGet(xu *xgbutil.XUtil, + win xproto.Window) (*WmIconGeometry, error) { + + geom, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "_NET_WM_ICON_GEOMETRY")) + if err != nil { + return nil, err + } + + return &WmIconGeometry{ + X: int(geom[0]), + Y: int(geom[1]), + Width: geom[2], + Height: geom[3], + }, nil +} + +// _NET_WM_ICON_GEOMETRY set +func WmIconGeometrySet(xu *xgbutil.XUtil, win xproto.Window, + geom *WmIconGeometry) error { + + rawGeom := make([]uint, 4) + rawGeom[0] = uint(geom.X) + rawGeom[1] = uint(geom.Y) + rawGeom[2] = geom.Width + rawGeom[3] = geom.Height + + return xprop.ChangeProp32(xu, win, "_NET_WM_ICON_GEOMETRY", "CARDINAL", + rawGeom...) +} + +// _NET_WM_ICON_NAME get +func WmIconNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { + return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_ICON_NAME")) +} + +// _NET_WM_ICON_NAME set +func WmIconNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { + return xprop.ChangeProp(xu, win, 8, "_NET_WM_ICON_NAME", "UTF8_STRING", + []byte(name)) +} + +// _NET_WM_MOVERESIZE constants +const ( + SizeTopLeft = iota + SizeTop + SizeTopRight + SizeRight + SizeBottomRight + SizeBottom + SizeBottomLeft + SizeLeft + Move + SizeKeyboard + MoveKeyboard + Cancel + Infer // special for Wingo. DO NOT USE. +) + +// _NET_WM_MOVERESIZE req +func WmMoveresize(xu *xgbutil.XUtil, win xproto.Window, direction int) error { + return WmMoveresizeExtra(xu, win, direction, 0, 0, 0, 2) +} + +// _NET_WM_MOVERESIZE req extra +func WmMoveresizeExtra(xu *xgbutil.XUtil, win xproto.Window, direction, + xRoot, yRoot, button, source int) error { + + return ClientEvent(xu, win, "_NET_WM_MOVERESIZE", + xRoot, yRoot, direction, button, source) +} + +// _NET_WM_NAME get +func WmNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { + return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_NAME")) +} + +// _NET_WM_NAME set +func WmNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { + return xprop.ChangeProp(xu, win, 8, "_NET_WM_NAME", "UTF8_STRING", + []byte(name)) +} + +// WmOpaqueRegion organizes information related to the _NET_WM_OPAQUE_REGION +// property. Namely, the x, y, width and height of an opaque rectangle +// relative to the client window. +type WmOpaqueRegion struct { + X int + Y int + Width uint + Height uint +} + +// _NET_WM_OPAQUE_REGION get +func WmOpaqueRegionGet(xu *xgbutil.XUtil, + win xproto.Window) ([]WmOpaqueRegion, error) { + + raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "_NET_WM_OPAQUE_REGION")) + if err != nil { + return nil, err + } + + regions := make([]WmOpaqueRegion, len(raw)/4) + for i, _ := range regions { + regions[i] = WmOpaqueRegion{ + X: int(raw[i*4+0]), + Y: int(raw[i*4+1]), + Width: raw[i*4+2], + Height: raw[i*4+3], + } + } + return regions, nil +} + +// _NET_WM_OPAQUE_REGION set +func WmOpaqueRegionSet(xu *xgbutil.XUtil, win xproto.Window, + regions []WmOpaqueRegion) error { + + raw := make([]uint, len(regions)*4) + + for i, region := range regions { + raw[i*4+0] = uint(region.X) + raw[i*4+1] = uint(region.Y) + raw[i*4+2] = region.Width + raw[i*4+3] = region.Height + } + + return xprop.ChangeProp32(xu, win, "_NET_WM_OPAQUE_REGION", "CARDINAL", + raw...) +} + +// _NET_WM_PID get +func WmPidGet(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { + return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_PID")) +} + +// _NET_WM_PID set +func WmPidSet(xu *xgbutil.XUtil, win xproto.Window, pid uint) error { + return xprop.ChangeProp32(xu, win, "_NET_WM_PID", "CARDINAL", pid) +} + +// _NET_WM_PING req +func WmPing(xu *xgbutil.XUtil, win xproto.Window, response bool) error { + return WmPingExtra(xu, win, response, 0) +} + +// _NET_WM_PING req extra +func WmPingExtra(xu *xgbutil.XUtil, win xproto.Window, response bool, + time xproto.Timestamp) error { + + pingAtom, err := xprop.Atm(xu, "_NET_WM_PING") + if err != nil { + return err + } + + var evWindow xproto.Window + if response { + evWindow = xu.RootWin() + } else { + evWindow = win + } + + return ClientEvent(xu, evWindow, "WM_PROTOCOLS", int(pingAtom), int(time), + int(win)) +} + +// _NET_WM_STATE constants for state toggling +// These correspond to the "action" parameter. +const ( + StateRemove = iota + StateAdd + StateToggle +) + +// _NET_WM_STATE get +func WmStateGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { + raw, err := xprop.GetProperty(xu, win, "_NET_WM_STATE") + return xprop.PropValAtoms(xu, raw, err) +} + +// _NET_WM_STATE set +func WmStateSet(xu *xgbutil.XUtil, win xproto.Window, + atomNames []string) error { + + atoms, err := xprop.StrToAtoms(xu, atomNames) + if err != nil { + return err + } + + return xprop.ChangeProp32(xu, win, "_NET_WM_STATE", "ATOM", atoms...) +} + +// _NET_WM_STATE req +func WmStateReq(xu *xgbutil.XUtil, win xproto.Window, action int, + atomName string) error { + + return WmStateReqExtra(xu, win, action, atomName, "", 2) +} + +// _NET_WM_STATE req extra +func WmStateReqExtra(xu *xgbutil.XUtil, win xproto.Window, action int, + first string, second string, source int) (err error) { + + var atom1, atom2 xproto.Atom + + atom1, err = xprop.Atom(xu, first, false) + if err != nil { + return err + } + + if len(second) > 0 { + atom2, err = xprop.Atom(xu, second, false) + if err != nil { + return err + } + } else { + atom2 = 0 + } + + return ClientEvent(xu, win, "_NET_WM_STATE", action, int(atom1), int(atom2), + source) +} + +// WmStrut struct organizes information for the _NET_WM_STRUT property. +// Namely, it encapsulates its four values: left, right, top and bottom. +type WmStrut struct { + Left uint + Right uint + Top uint + Bottom uint +} + +// _NET_WM_STRUT get +func WmStrutGet(xu *xgbutil.XUtil, win xproto.Window) (*WmStrut, error) { + struts, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "_NET_WM_STRUT")) + if err != nil { + return nil, err + } + + return &WmStrut{ + Left: struts[0], + Right: struts[1], + Top: struts[2], + Bottom: struts[3], + }, nil +} + +// _NET_WM_STRUT set +func WmStrutSet(xu *xgbutil.XUtil, win xproto.Window, struts *WmStrut) error { + rawStruts := make([]uint, 4) + rawStruts[0] = struts.Left + rawStruts[1] = struts.Right + rawStruts[2] = struts.Top + rawStruts[3] = struts.Bottom + + return xprop.ChangeProp32(xu, win, "_NET_WM_STRUT", "CARDINAL", + rawStruts...) +} + +// WmStrutPartial struct organizes information for the _NET_WM_STRUT_PARTIAL +// property. Namely, it encapsulates its twelve values: left, right, top, +// bottom, left_start_y, left_end_y, right_start_y, right_end_y, +// top_start_x, top_end_x, bottom_start_x, and bottom_end_x. +type WmStrutPartial struct { + Left, Right, Top, Bottom uint + LeftStartY, LeftEndY, RightStartY, RightEndY uint + TopStartX, TopEndX, BottomStartX, BottomEndX uint +} + +// _NET_WM_STRUT_PARTIAL get +func WmStrutPartialGet(xu *xgbutil.XUtil, + win xproto.Window) (*WmStrutPartial, error) { + + struts, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "_NET_WM_STRUT_PARTIAL")) + if err != nil { + return nil, err + } + + return &WmStrutPartial{ + Left: struts[0], Right: struts[1], Top: struts[2], Bottom: struts[3], + LeftStartY: struts[4], LeftEndY: struts[5], + RightStartY: struts[6], RightEndY: struts[7], + TopStartX: struts[8], TopEndX: struts[9], + BottomStartX: struts[10], BottomEndX: struts[11], + }, nil +} + +// _NET_WM_STRUT_PARTIAL set +func WmStrutPartialSet(xu *xgbutil.XUtil, win xproto.Window, + struts *WmStrutPartial) error { + + rawStruts := make([]uint, 12) + rawStruts[0] = struts.Left + rawStruts[1] = struts.Right + rawStruts[2] = struts.Top + rawStruts[3] = struts.Bottom + rawStruts[4] = struts.LeftStartY + rawStruts[5] = struts.LeftEndY + rawStruts[6] = struts.RightStartY + rawStruts[7] = struts.RightEndY + rawStruts[8] = struts.TopStartX + rawStruts[9] = struts.TopEndX + rawStruts[10] = struts.BottomStartX + rawStruts[11] = struts.BottomEndX + + return xprop.ChangeProp32(xu, win, "_NET_WM_STRUT_PARTIAL", "CARDINAL", + rawStruts...) +} + +// _NET_WM_SYNC_REQUEST req +func WmSyncRequest(xu *xgbutil.XUtil, win xproto.Window, req_num uint64) error { + return WmSyncRequestExtra(xu, win, req_num, 0) +} + +// _NET_WM_SYNC_REQUEST req extra +func WmSyncRequestExtra(xu *xgbutil.XUtil, win xproto.Window, reqNum uint64, + time xproto.Timestamp) error { + + syncReq, err := xprop.Atm(xu, "_NET_WM_SYNC_REQUEST") + if err != nil { + return err + } + + high := int(reqNum >> 32) + low := int(reqNum<<32 ^ reqNum) + + return ClientEvent(xu, win, "WM_PROTOCOLS", int(syncReq), int(time), + low, high) +} + +// _NET_WM_SYNC_REQUEST_COUNTER get +// I'm pretty sure this needs 64 bit integers, but I'm not quite sure +// how to go about that yet. Any ideas? +func WmSyncRequestCounter(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { + return xprop.PropValNum(xprop.GetProperty(xu, win, + "_NET_WM_SYNC_REQUEST_COUNTER")) +} + +// _NET_WM_SYNC_REQUEST_COUNTER set +// I'm pretty sure this needs 64 bit integers, but I'm not quite sure +// how to go about that yet. Any ideas? +func WmSyncRequestCounterSet(xu *xgbutil.XUtil, win xproto.Window, + counter uint) error { + + return xprop.ChangeProp32(xu, win, "_NET_WM_SYNC_REQUEST_COUNTER", + "CARDINAL", counter) +} + +// _NET_WM_USER_TIME get +func WmUserTimeGet(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { + return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_USER_TIME")) +} + +// _NET_WM_USER_TIME set +func WmUserTimeSet(xu *xgbutil.XUtil, win xproto.Window, userTime uint) error { + return xprop.ChangeProp32(xu, win, "_NET_WM_USER_TIME", "CARDINAL", + userTime) +} + +// _NET_WM_USER_TIME_WINDOW get +func WmUserTimeWindowGet(xu *xgbutil.XUtil, + win xproto.Window) (xproto.Window, error) { + + return xprop.PropValWindow(xprop.GetProperty(xu, win, + "_NET_WM_USER_TIME_WINDOW")) +} + +// _NET_WM_USER_TIME set +func WmUserTimeWindowSet(xu *xgbutil.XUtil, win xproto.Window, + timeWin xproto.Window) error { + + return xprop.ChangeProp32(xu, win, "_NET_WM_USER_TIME_WINDOW", "CARDINAL", + uint(timeWin)) +} + +// _NET_WM_VISIBLE_ICON_NAME get +func WmVisibleIconNameGet(xu *xgbutil.XUtil, + win xproto.Window) (string, error) { + + return xprop.PropValStr(xprop.GetProperty(xu, win, + "_NET_WM_VISIBLE_ICON_NAME")) +} + +// _NET_WM_VISIBLE_ICON_NAME set +func WmVisibleIconNameSet(xu *xgbutil.XUtil, win xproto.Window, + name string) error { + + return xprop.ChangeProp(xu, win, 8, "_NET_WM_VISIBLE_ICON_NAME", + "UTF8_STRING", []byte(name)) +} + +// _NET_WM_VISIBLE_NAME get +func WmVisibleNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { + return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_VISIBLE_NAME")) +} + +// _NET_WM_VISIBLE_NAME set +func WmVisibleNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { + return xprop.ChangeProp(xu, win, 8, "_NET_WM_VISIBLE_NAME", "UTF8_STRING", + []byte(name)) +} + +// _NET_WM_WINDOW_OPACITY get +// This isn't part of the EWMH spec, but is widely used by drop in +// compositing managers (i.e., xcompmgr, cairo-compmgr, etc.). +// This property is typically set not on a client window, but the *parent* +// of a client window in reparenting window managers. +// The float returned will be in the range [0.0, 1.0] where 0.0 is completely +// transparent and 1.0 is completely opaque. +func WmWindowOpacityGet(xu *xgbutil.XUtil, win xproto.Window) (float64, error) { + intOpacity, err := xprop.PropValNum( + xprop.GetProperty(xu, win, "_NET_WM_WINDOW_OPACITY")) + if err != nil { + return 0, err + } + + return float64(uint(intOpacity)) / float64(0xffffffff), nil +} + +// _NET_WM_WINDOW_OPACITY set +func WmWindowOpacitySet(xu *xgbutil.XUtil, win xproto.Window, + opacity float64) error { + + return xprop.ChangeProp32(xu, win, "_NET_WM_WINDOW_OPACITY", "CARDINAL", + uint(opacity*0xffffffff)) +} + +// _NET_WM_WINDOW_TYPE get +func WmWindowTypeGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { + raw, err := xprop.GetProperty(xu, win, "_NET_WM_WINDOW_TYPE") + return xprop.PropValAtoms(xu, raw, err) +} + +// _NET_WM_WINDOW_TYPE set +// This will create any atoms used in 'atomNames' if they don't already exist. +func WmWindowTypeSet(xu *xgbutil.XUtil, win xproto.Window, + atomNames []string) error { + + atoms, err := xprop.StrToAtoms(xu, atomNames) + if err != nil { + return err + } + return xprop.ChangeProp32(xu, win, "_NET_WM_WINDOW_TYPE", "ATOM", atoms...) +} + +// Workarea is a struct that represents a rectangle as a bounding box of +// a single desktop. So there should be as many Workarea structs as there +// are desktops. +type Workarea struct { + X int + Y int + Width uint + Height uint +} + +// _NET_WORKAREA get +func WorkareaGet(xu *xgbutil.XUtil) ([]Workarea, error) { + rects, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), + "_NET_WORKAREA")) + if err != nil { + return nil, err + } + + workareas := make([]Workarea, len(rects)/4) + for i, _ := range workareas { + workareas[i] = Workarea{ + X: int(rects[i*4]), + Y: int(rects[i*4+1]), + Width: rects[i*4+2], + Height: rects[i*4+3], + } + } + return workareas, nil +} + +// _NET_WORKAREA set +func WorkareaSet(xu *xgbutil.XUtil, workareas []Workarea) error { + rects := make([]uint, len(workareas)*4) + for i, workarea := range workareas { + rects[i*4+0] = uint(workarea.X) + rects[i*4+1] = uint(workarea.Y) + rects[i*4+2] = workarea.Width + rects[i*4+3] = workarea.Height + } + + return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_WORKAREA", "CARDINAL", + rects...) +} diff --git a/vend/xgbutil/ewmh/winman.go b/vend/xgbutil/ewmh/winman.go new file mode 100644 index 0000000..f06151d --- /dev/null +++ b/vend/xgbutil/ewmh/winman.go @@ -0,0 +1,31 @@ +package ewmh + +import ( + "fmt" + + "github.com/jezek/xgbutil" +) + +// GetEwmhWM uses the EWMH spec to find if a conforming window manager +// is currently running or not. If it is, then its name will be returned. +// Otherwise, an error will be returned explaining why one couldn't be found. +func GetEwmhWM(xu *xgbutil.XUtil) (string, error) { + childCheck, err := SupportingWmCheckGet(xu, xu.RootWin()) + if err != nil { + return "", fmt.Errorf("GetEwmhWM: Failed because: %s", err) + } + + childCheck2, err := SupportingWmCheckGet(xu, childCheck) + if err != nil { + return "", fmt.Errorf("GetEwmhWM: Failed because: %s", err) + } + + if childCheck != childCheck2 { + return "", fmt.Errorf( + "GetEwmhWM: _NET_SUPPORTING_WM_CHECK value on the root window "+ + "(%x) does not match _NET_SUPPORTING_WM_CHECK value "+ + "on the child window (%x).", childCheck, childCheck2) + } + + return WmNameGet(xu, childCheck) +} diff --git a/vend/xgbutil/go.mod b/vend/xgbutil/go.mod new file mode 100644 index 0000000..c3941f9 --- /dev/null +++ b/vend/xgbutil/go.mod @@ -0,0 +1,9 @@ +module github.com/jezek/xgbutil + +go 1.11 + +require ( + github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 + github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 + github.com/jezek/xgb v1.1.0 +) diff --git a/vend/xgbutil/go.sum b/vend/xgbutil/go.sum new file mode 100644 index 0000000..b307602 --- /dev/null +++ b/vend/xgbutil/go.sum @@ -0,0 +1,6 @@ +github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 h1:1qlsVAQJXZHsaM8b6OLVo6muQUQd4CwkH/D3fnnbHXA= +github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ= +github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 h1:lTG4HQym5oPKjL7nGs+csTgiDna685ZXjxijkne828g= +github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0= +github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk= +github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= diff --git a/vend/xgbutil/gopher/doc.go b/vend/xgbutil/gopher/doc.go new file mode 100644 index 0000000..75e723a --- /dev/null +++ b/vend/xgbutil/gopher/doc.go @@ -0,0 +1,8 @@ +/* +Package gopher contains a single image of the Go gopher. It is included to +guarantee that at least one image is always available for some examples +to run successfully. + +This file was automatically generated by go-bindata. +*/ +package gopher diff --git a/vend/xgbutil/gopher/gopher.go b/vend/xgbutil/gopher/gopher.go new file mode 100644 index 0000000..bd5f052 --- /dev/null +++ b/vend/xgbutil/gopher/gopher.go @@ -0,0 +1,3785 @@ +package gopher + +import ( + "bytes" + "compress/gzip" + "io" +) + +// GopherPng returns the raw, uncompressed file data data. +func GopherPng() []byte { + gz, err := gzip.NewReader(bytes.NewBuffer([]byte{ + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0x34, 0x9b, + 0x05, 0x50, 0x5d, 0x4d, 0xd3, 0xad, 0x0f, 0xee, 0x12, 0xf4, 0x20, 0x81, + 0xe0, 0x04, 0x77, 0xf7, 0x60, 0xc1, 0xdd, 0x9d, 0xe0, 0xee, 0xee, 0xee, + 0x21, 0xb8, 0x3b, 0x04, 0x87, 0xe0, 0xee, 0xf0, 0x62, 0xc1, 0x35, 0xb8, + 0xbb, 0xbb, 0xde, 0x4d, 0x7d, 0xf7, 0x4f, 0x55, 0x8a, 0x02, 0x4e, 0xd5, + 0xee, 0xdd, 0xd3, 0xbd, 0xfa, 0x59, 0x33, 0x43, 0x84, 0x82, 0x9c, 0x04, + 0x0a, 0x22, 0x3e, 0x22, 0x08, 0x04, 0x42, 0xf9, 0x2e, 0x29, 0xaa, 0x04, + 0x02, 0x41, 0xdc, 0x7c, 0xfc, 0x87, 0x87, 0x05, 0x7e, 0x32, 0x3a, 0xbf, + 0x1e, 0x09, 0x7c, 0x81, 0x76, 0x12, 0xf9, 0xae, 0x02, 0x0f, 0xfc, 0xf3, + 0x86, 0xff, 0x11, 0x0e, 0x02, 0x7d, 0x01, 0x7d, 0x17, 0x15, 0x56, 0x71, + 0xcf, 0x3c, 0xc9, 0x72, 0x53, 0x51, 0x19, 0xc2, 0x1d, 0xea, 0xb2, 0xa3, + 0x6d, 0xbb, 0x61, 0x90, 0x52, 0x45, 0xff, 0x1a, 0x08, 0x53, 0x43, 0x8a, + 0xe8, 0xda, 0xaf, 0x67, 0x6c, 0xf7, 0x5d, 0x26, 0xba, 0x76, 0x00, 0x1c, + 0x33, 0xb8, 0x83, 0xcb, 0xde, 0x88, 0x15, 0x13, 0x31, 0x08, 0x96, 0xa5, + 0xfb, 0x1e, 0x1d, 0xc1, 0x7f, 0x87, 0x31, 0xb0, 0xa6, 0x88, 0x8e, 0x04, + 0x09, 0x39, 0xcd, 0x6b, 0xbd, 0x7e, 0xef, 0xeb, 0x97, 0x8b, 0x24, 0x8d, + 0x99, 0xac, 0xeb, 0x1a, 0xf0, 0x98, 0x99, 0xe0, 0x94, 0xf9, 0xbc, 0x37, + 0xae, 0x83, 0x72, 0xb2, 0xda, 0xe2, 0x84, 0x24, 0xf4, 0x05, 0x1d, 0x1e, + 0x1a, 0x32, 0xaf, 0xa7, 0x6f, 0xbe, 0x09, 0x12, 0x1a, 0x52, 0xb8, 0xed, + 0xe1, 0xf1, 0xb4, 0xf0, 0x4f, 0x5d, 0x4e, 0xda, 0xd3, 0x53, 0x55, 0x92, + 0x34, 0x39, 0x5d, 0x80, 0x4c, 0xf2, 0x39, 0x0a, 0xfc, 0xc9, 0x92, 0x75, + 0x14, 0x07, 0x72, 0x90, 0x2b, 0xa8, 0x0b, 0xc5, 0x60, 0x36, 0x74, 0xc8, + 0xe9, 0x20, 0x5f, 0xe5, 0x0a, 0x2f, 0xa0, 0x5b, 0x5f, 0x58, 0x71, 0x9e, + 0x50, 0x7f, 0xbd, 0xfa, 0xc7, 0xe1, 0x21, 0xdc, 0x6d, 0xa5, 0x40, 0x80, + 0xd0, 0x24, 0xba, 0xd4, 0x3a, 0x22, 0x3a, 0x7c, 0x70, 0x3a, 0x19, 0x96, + 0xeb, 0x16, 0x2d, 0x96, 0x07, 0x89, 0x94, 0x49, 0x80, 0x42, 0x29, 0x1d, + 0x4e, 0x9d, 0x06, 0xa1, 0x76, 0x68, 0x7c, 0x1b, 0x6b, 0xb4, 0x0c, 0xa8, + 0x06, 0x1a, 0x6b, 0xa0, 0x1e, 0x6e, 0x63, 0x90, 0xe9, 0x0a, 0x07, 0x44, + 0x8b, 0x9b, 0xfb, 0xe8, 0xaf, 0xa4, 0xf1, 0x5a, 0x56, 0xa1, 0xfe, 0x5e, + 0xab, 0xaf, 0x80, 0xc5, 0xf8, 0xcb, 0x50, 0x83, 0xaa, 0x59, 0xe7, 0xf9, + 0x19, 0xcb, 0x04, 0x83, 0x2c, 0x61, 0x55, 0x71, 0xb6, 0x4f, 0x3f, 0xea, + 0x23, 0xbe, 0xe0, 0xc1, 0xa8, 0xa4, 0x39, 0x78, 0xb2, 0xee, 0xa9, 0xa0, + 0xf1, 0xc6, 0xd7, 0x9f, 0xf9, 0xd0, 0x12, 0xa0, 0x33, 0x3f, 0x10, 0x27, + 0x1c, 0x48, 0x59, 0xf0, 0xfd, 0x12, 0x0b, 0x24, 0x08, 0x81, 0x4e, 0x68, + 0x50, 0x6b, 0x6d, 0x5a, 0xa7, 0x61, 0x4b, 0xe4, 0xeb, 0xcb, 0xab, 0x79, + 0x7b, 0x95, 0x52, 0x2d, 0x51, 0x51, 0x41, 0xa9, 0x79, 0xa8, 0x0d, 0x07, + 0x29, 0x4c, 0xf0, 0x13, 0x93, 0x27, 0xc0, 0x00, 0x54, 0xa3, 0x61, 0x8b, + 0x43, 0x18, 0xeb, 0xf8, 0x53, 0x26, 0x79, 0x2a, 0x33, 0x7f, 0x91, 0x01, + 0xb4, 0x3d, 0xc1, 0x74, 0x85, 0xea, 0xaf, 0xa3, 0x30, 0xc3, 0x3e, 0x26, + 0x13, 0x6c, 0xef, 0x5c, 0x03, 0x13, 0x36, 0x1e, 0x18, 0x96, 0x41, 0xe6, + 0x09, 0xdd, 0x10, 0xe2, 0x3f, 0x11, 0x94, 0x14, 0xf2, 0x15, 0x5a, 0xdc, + 0x7b, 0x07, 0x17, 0x87, 0x6c, 0x6f, 0x09, 0x29, 0xbc, 0x1f, 0x23, 0x15, + 0x3f, 0x85, 0x6e, 0x74, 0xff, 0xda, 0xc0, 0xd8, 0x10, 0x36, 0x5e, 0x34, + 0x12, 0xf3, 0x7d, 0xb5, 0xb7, 0x12, 0x4e, 0xfe, 0x67, 0x52, 0x82, 0xfe, + 0x38, 0xc3, 0x0a, 0x61, 0xe4, 0xd6, 0x2a, 0xb4, 0xc6, 0xbb, 0x03, 0xd7, + 0xb8, 0xdc, 0xe8, 0xee, 0xd5, 0x3f, 0x21, 0x48, 0xe5, 0x85, 0x2e, 0x3f, + 0x9f, 0x3e, 0xa3, 0x86, 0x3d, 0x65, 0x95, 0x29, 0x95, 0xf4, 0xbf, 0x39, + 0xe3, 0x4c, 0x18, 0x8c, 0xfe, 0x59, 0xa2, 0x8a, 0x2f, 0xd6, 0xa1, 0x86, + 0xaf, 0x23, 0xbb, 0x1c, 0xbc, 0x3d, 0x46, 0xdc, 0x7f, 0x02, 0xa0, 0xa9, + 0xec, 0xce, 0x6d, 0x4a, 0xce, 0xd6, 0x50, 0xe6, 0x9a, 0x5a, 0xa1, 0x45, + 0x62, 0xbe, 0xc0, 0x66, 0x09, 0x4d, 0x42, 0x29, 0x97, 0x48, 0xfd, 0xe6, + 0xf7, 0x82, 0xd4, 0xc1, 0x8a, 0x3c, 0x59, 0xf3, 0x37, 0xc7, 0x90, 0xc5, + 0x75, 0x81, 0x4c, 0x6c, 0x1f, 0xd9, 0xe3, 0xe1, 0x5e, 0xec, 0x5d, 0x6f, + 0xc3, 0x1e, 0x93, 0x8d, 0x21, 0x61, 0xdb, 0xea, 0x9b, 0x5e, 0x81, 0xa6, + 0xc3, 0x81, 0x81, 0xe3, 0xb5, 0xba, 0x68, 0x26, 0x5c, 0xd4, 0xd2, 0xf6, + 0x9f, 0xd8, 0xee, 0xed, 0xf9, 0x8b, 0x48, 0xe8, 0xba, 0xda, 0x6b, 0x64, + 0x9e, 0x2e, 0xee, 0xa9, 0xc6, 0x10, 0x39, 0xa0, 0xb4, 0x83, 0x8b, 0x55, + 0x20, 0x49, 0x0e, 0x0b, 0xc2, 0x8a, 0xe8, 0x0f, 0x6f, 0xc7, 0x8b, 0xa9, + 0x4b, 0x39, 0x17, 0xa2, 0x64, 0x3c, 0x0e, 0xd9, 0x2f, 0x52, 0xc0, 0x3a, + 0x27, 0x14, 0xbb, 0xb4, 0x45, 0x82, 0xfe, 0x4b, 0x15, 0x19, 0x75, 0xce, + 0x5f, 0x95, 0x00, 0xc9, 0xd3, 0xbb, 0xc8, 0xb5, 0x28, 0x45, 0xfa, 0xdd, + 0x41, 0x99, 0xa6, 0x4e, 0x67, 0xc9, 0x5a, 0xad, 0x59, 0x49, 0x93, 0x0d, + 0x5e, 0x61, 0x51, 0x4d, 0xa0, 0xed, 0xc6, 0x38, 0x3e, 0x9f, 0xee, 0xad, + 0x90, 0xfa, 0x8d, 0x43, 0xa0, 0x6b, 0x57, 0xac, 0xf6, 0x21, 0xb2, 0x3d, + 0x7b, 0x96, 0x02, 0x9d, 0x2d, 0x10, 0xec, 0x0c, 0x99, 0x97, 0xcd, 0xc4, + 0x62, 0x69, 0x47, 0x9e, 0x52, 0x72, 0x5f, 0x70, 0x98, 0xff, 0xe6, 0xdf, + 0xce, 0xda, 0x27, 0xb9, 0x9c, 0xe4, 0xde, 0x44, 0xbb, 0x65, 0x60, 0x16, + 0xb3, 0xf9, 0xda, 0x96, 0x27, 0x7f, 0x8f, 0x6a, 0x6f, 0x61, 0x88, 0x16, + 0xc9, 0x12, 0xad, 0x3f, 0x67, 0x86, 0xc0, 0x58, 0x6b, 0x3a, 0x9a, 0xd3, + 0x7c, 0xbb, 0x81, 0x00, 0x2e, 0x6e, 0x3f, 0xa3, 0x83, 0xdd, 0x58, 0x83, + 0xd4, 0x88, 0xa7, 0x4b, 0x1e, 0xf6, 0xc1, 0x4c, 0xb0, 0x35, 0x43, 0x44, + 0x44, 0x2d, 0x3e, 0x10, 0x53, 0x04, 0xe9, 0x54, 0x85, 0x61, 0xca, 0xee, + 0xfb, 0xe4, 0xaa, 0xe0, 0xdc, 0xc0, 0x62, 0xd9, 0x40, 0x50, 0x94, 0xa0, + 0x96, 0x47, 0x7c, 0x8d, 0x24, 0x80, 0xb1, 0x67, 0x54, 0x4e, 0x7c, 0x44, + 0xe0, 0x6d, 0x8b, 0x48, 0x99, 0x9e, 0x56, 0x93, 0xaa, 0x2f, 0xa1, 0x0f, + 0x50, 0x70, 0x43, 0xde, 0x56, 0x0e, 0x14, 0x32, 0x2f, 0xbc, 0x70, 0x7f, + 0x33, 0x65, 0xcb, 0x62, 0x56, 0x29, 0xa5, 0xc3, 0x1f, 0x64, 0xda, 0x62, + 0x12, 0x32, 0xd4, 0xf2, 0x8d, 0xfd, 0x94, 0x13, 0x85, 0x73, 0xc7, 0x71, + 0xb0, 0xd8, 0xc8, 0xde, 0xea, 0x7a, 0x13, 0xea, 0xe4, 0xc4, 0x5b, 0xef, + 0xec, 0x3a, 0x19, 0xd6, 0xca, 0x4e, 0xc9, 0x4d, 0x8f, 0xf4, 0x9e, 0xdd, + 0x15, 0xf0, 0x50, 0xa8, 0xb2, 0xe2, 0x7b, 0x81, 0x85, 0xb7, 0xe4, 0x91, + 0x34, 0x66, 0x34, 0x0c, 0x71, 0x46, 0x81, 0x3a, 0xb4, 0xf5, 0x45, 0x8c, + 0xfb, 0x8d, 0x3e, 0x65, 0xdd, 0x57, 0x93, 0xb8, 0xd5, 0xa1, 0x25, 0xfb, + 0x2f, 0xa2, 0xd8, 0x91, 0x51, 0xe8, 0x27, 0x59, 0x28, 0x2c, 0x6f, 0xdd, + 0x93, 0x1e, 0xa3, 0x34, 0x72, 0xe0, 0xf9, 0x52, 0xbc, 0x6d, 0x35, 0x39, + 0xca, 0xca, 0x7e, 0x64, 0x01, 0x41, 0xd0, 0x41, 0xfe, 0xc0, 0xfb, 0x0b, + 0x5b, 0x35, 0x07, 0x0e, 0xb1, 0xde, 0x29, 0x52, 0x2b, 0x79, 0xcd, 0xd4, + 0xff, 0xc6, 0xec, 0x7e, 0x80, 0x92, 0xe2, 0x14, 0x52, 0xdc, 0x24, 0x6a, + 0x97, 0xa5, 0xa5, 0x42, 0x3e, 0xc0, 0x0b, 0xde, 0xbb, 0x9b, 0x3f, 0x58, + 0x59, 0x93, 0x76, 0x29, 0xa9, 0x44, 0xfa, 0xe3, 0x84, 0x74, 0xb1, 0x65, + 0x02, 0xdb, 0x4c, 0x88, 0xfa, 0xe0, 0xcd, 0x80, 0x18, 0x35, 0x40, 0x4d, + 0x4d, 0xa7, 0xc6, 0xbf, 0x7f, 0xdd, 0x6c, 0xef, 0x62, 0x0d, 0x4b, 0x20, + 0xcd, 0x6a, 0xdf, 0xd2, 0x20, 0xd8, 0x4f, 0x63, 0x81, 0xaf, 0x18, 0x97, + 0x4d, 0x76, 0xa5, 0xc6, 0x86, 0xf1, 0x6b, 0x06, 0xfd, 0x95, 0xfc, 0x93, + 0x45, 0x1a, 0xf7, 0xae, 0x69, 0xad, 0x79, 0xe4, 0x1f, 0x2e, 0x4b, 0x13, + 0x6c, 0x1e, 0x76, 0x5e, 0x2f, 0xbf, 0xc7, 0x30, 0xad, 0x80, 0x51, 0x9b, + 0xdd, 0x4a, 0x15, 0x53, 0x3f, 0xa9, 0x99, 0x90, 0x3e, 0x50, 0x91, 0xe2, + 0xe3, 0x3e, 0x96, 0x58, 0x4f, 0x4b, 0xcb, 0x67, 0x3e, 0x6d, 0x9e, 0xfc, + 0x96, 0x8e, 0xdb, 0x72, 0x37, 0xae, 0x9a, 0xba, 0x46, 0x7f, 0xa5, 0xef, + 0xdb, 0xc3, 0xd7, 0x3f, 0xda, 0xc7, 0xfe, 0x0b, 0xfd, 0x55, 0x6c, 0x48, + 0x83, 0xb5, 0xb1, 0xbc, 0x2a, 0x81, 0xfe, 0xbd, 0x70, 0xee, 0xec, 0xbb, + 0x62, 0xf1, 0x3e, 0x9e, 0x38, 0x17, 0x84, 0x64, 0x75, 0x0a, 0x23, 0x2d, + 0xb4, 0x88, 0x0b, 0x7a, 0x90, 0xdc, 0x17, 0xf3, 0xf0, 0xba, 0x6b, 0x29, + 0x5f, 0xa9, 0x91, 0x64, 0x50, 0x68, 0x7c, 0x13, 0x6c, 0xff, 0xb6, 0x85, + 0xd6, 0x0a, 0xea, 0x4f, 0x6d, 0xf5, 0x5d, 0x71, 0x3b, 0x43, 0xbb, 0xa0, + 0x1a, 0xdb, 0xd3, 0x29, 0xaa, 0x66, 0x28, 0x6f, 0xad, 0xb6, 0xc0, 0x22, + 0x13, 0x4e, 0x4f, 0xe1, 0x78, 0x78, 0x6e, 0x0f, 0x18, 0xc9, 0x89, 0x91, + 0x81, 0x99, 0x87, 0x94, 0x66, 0xef, 0x67, 0x12, 0x96, 0xba, 0xeb, 0x4f, + 0x39, 0x99, 0xb0, 0x45, 0xbf, 0x7c, 0xb7, 0x9f, 0x8b, 0x07, 0x45, 0x90, + 0x11, 0x8f, 0x83, 0xf1, 0x8c, 0xe1, 0xba, 0x97, 0x7b, 0x65, 0x8c, 0xf9, + 0x13, 0xa5, 0xf0, 0x39, 0xcf, 0x86, 0xb6, 0x9a, 0xfc, 0xe4, 0xb6, 0x97, + 0x57, 0x17, 0x1d, 0xab, 0x3c, 0x6c, 0x09, 0x33, 0x6c, 0x3a, 0xa6, 0xfa, + 0x0b, 0x87, 0xfe, 0xbe, 0xbc, 0xf8, 0xc0, 0xe0, 0xdb, 0x29, 0xc1, 0xd2, + 0x96, 0x0b, 0xdc, 0x3d, 0x3e, 0x36, 0x09, 0xaa, 0xd3, 0x20, 0x15, 0x43, + 0x21, 0xa2, 0x02, 0x0d, 0x8a, 0xe5, 0xe9, 0x7a, 0x17, 0x96, 0xd5, 0x00, + 0x73, 0x52, 0x41, 0xbf, 0x31, 0xb3, 0x8c, 0x5d, 0x15, 0x7b, 0x57, 0xd3, + 0x54, 0x5b, 0x71, 0xd9, 0xba, 0xe4, 0x11, 0xd2, 0xec, 0xbc, 0x0d, 0x71, + 0x47, 0xc4, 0x13, 0x46, 0x75, 0x39, 0x3c, 0x37, 0xb6, 0x33, 0x50, 0xab, + 0x81, 0x7a, 0x9e, 0x9e, 0xe1, 0xe7, 0xcc, 0xc1, 0xe9, 0xe6, 0x1a, 0x84, + 0x84, 0x4e, 0xce, 0x46, 0x14, 0x2e, 0x4c, 0x85, 0x6e, 0x19, 0x42, 0xfb, + 0xe0, 0xed, 0xaa, 0xdf, 0xc2, 0xe7, 0xf7, 0xa5, 0x0f, 0x2b, 0xce, 0x0c, + 0x5c, 0x2b, 0x6b, 0x52, 0xb7, 0x48, 0x87, 0xc3, 0xf3, 0xd0, 0xda, 0x57, + 0xd2, 0x40, 0x2b, 0x13, 0x13, 0x72, 0x61, 0x7b, 0x1a, 0xe8, 0xdf, 0x48, + 0xb4, 0xe1, 0x78, 0x64, 0x1f, 0xf3, 0x8c, 0x18, 0x6a, 0xa8, 0x40, 0x97, + 0x4c, 0xca, 0xc0, 0x0c, 0x23, 0x46, 0x8a, 0x60, 0x94, 0x4d, 0x4e, 0xca, + 0x4a, 0x45, 0x0c, 0x27, 0xaf, 0x1f, 0x20, 0xa3, 0x76, 0xdf, 0x4c, 0x4f, + 0x26, 0x80, 0xa6, 0x77, 0xf6, 0xb7, 0xa6, 0x81, 0x45, 0x22, 0x43, 0x4d, + 0xee, 0xa3, 0x98, 0xbc, 0xf9, 0x75, 0x7b, 0x4c, 0xe7, 0x04, 0x8c, 0x4f, + 0xf5, 0x64, 0x08, 0xe5, 0x24, 0xd6, 0x84, 0x75, 0xb6, 0xa4, 0x57, 0xa2, + 0x3d, 0x75, 0xf6, 0xa2, 0x60, 0x38, 0xe3, 0x46, 0x5d, 0x5e, 0x94, 0x18, + 0xcc, 0x3a, 0xa1, 0x30, 0xd8, 0x9c, 0x35, 0xdb, 0x94, 0xf8, 0x88, 0x1a, + 0x44, 0x29, 0xa5, 0xd3, 0xd0, 0xfe, 0x53, 0x29, 0x35, 0x43, 0x75, 0x55, + 0x7b, 0x58, 0x7f, 0xf9, 0x0a, 0x7f, 0x61, 0x55, 0xb9, 0xf4, 0x67, 0xf7, + 0xa7, 0xa4, 0xc9, 0xc3, 0xf1, 0x7a, 0x14, 0x97, 0xeb, 0x19, 0x2c, 0x91, + 0xa0, 0x7c, 0x19, 0xb9, 0x6b, 0x2e, 0x34, 0xc3, 0xc2, 0xa1, 0x79, 0x9d, + 0x69, 0x9f, 0x38, 0x05, 0x85, 0x0d, 0xb9, 0xdb, 0x31, 0x74, 0x87, 0x10, + 0x32, 0x4f, 0x80, 0x02, 0x54, 0x70, 0x2f, 0xd1, 0x9d, 0x91, 0xc3, 0xac, + 0xb9, 0x90, 0x40, 0x90, 0x61, 0xe4, 0x6b, 0x59, 0xba, 0x99, 0xb1, 0x49, + 0x6c, 0x78, 0xcd, 0x5f, 0xb0, 0x20, 0x1b, 0x16, 0x47, 0xf2, 0x9e, 0xd6, + 0x9c, 0x30, 0x65, 0xc2, 0xf6, 0x74, 0x65, 0x18, 0x97, 0xf7, 0x1e, 0x0d, + 0xc3, 0x7a, 0x74, 0xa8, 0x48, 0xe9, 0xec, 0xd1, 0xd3, 0xdc, 0xe6, 0x81, + 0x41, 0x14, 0x73, 0x90, 0x08, 0x3a, 0xd1, 0x32, 0x82, 0xda, 0x1e, 0x76, + 0x2f, 0x68, 0x0d, 0xbe, 0x8f, 0x49, 0xf2, 0xfb, 0xc4, 0x60, 0x00, 0x66, + 0xfc, 0xc3, 0x73, 0x3f, 0xc5, 0x0e, 0x76, 0xbb, 0xeb, 0x23, 0x01, 0x3f, + 0xd4, 0xc3, 0x31, 0x17, 0x61, 0x58, 0xb9, 0x80, 0xc0, 0x73, 0xc1, 0xf9, + 0xfa, 0xbd, 0x4f, 0x1d, 0x2d, 0x04, 0x28, 0x6a, 0x6e, 0x3a, 0xb2, 0x78, + 0xa6, 0x09, 0x6a, 0xe0, 0xdb, 0xe8, 0x08, 0x59, 0x2f, 0xcf, 0x76, 0x81, + 0x9b, 0x78, 0xdf, 0xd8, 0x0e, 0x4a, 0x83, 0x33, 0x9b, 0xbf, 0x21, 0x98, + 0x4f, 0x5e, 0xaa, 0xaf, 0x38, 0x0b, 0xce, 0x61, 0x73, 0xf9, 0x95, 0xc6, + 0x14, 0xc1, 0x16, 0x21, 0xc4, 0x46, 0x00, 0x3d, 0xe2, 0x4c, 0x6f, 0xa6, + 0x15, 0x12, 0xba, 0x97, 0xe0, 0x43, 0xb3, 0x7e, 0x43, 0x2a, 0xcf, 0x30, + 0xc4, 0x92, 0x2a, 0xae, 0xa8, 0xa4, 0x33, 0x1c, 0x0d, 0x32, 0x4d, 0x9f, + 0xf9, 0x4f, 0x37, 0x9f, 0x38, 0x45, 0xe6, 0xa3, 0x1f, 0x9c, 0x23, 0xc8, + 0x73, 0x4a, 0xa4, 0x66, 0xe0, 0x17, 0x48, 0x50, 0x09, 0xd6, 0x3b, 0xba, + 0x82, 0x32, 0x2a, 0x57, 0x97, 0x69, 0x91, 0xfb, 0x36, 0xba, 0x87, 0x47, + 0x1f, 0x1c, 0xee, 0x3f, 0xfd, 0x50, 0xcb, 0x20, 0xd3, 0xe3, 0xd6, 0x61, + 0xc0, 0xe5, 0x23, 0x42, 0x43, 0xee, 0x13, 0x22, 0xc7, 0x98, 0xfb, 0x8e, + 0x9b, 0xf7, 0x89, 0xd8, 0x18, 0xee, 0xbe, 0xb7, 0x7e, 0xea, 0xd5, 0x80, + 0x74, 0xf6, 0x64, 0xad, 0x4b, 0x83, 0xae, 0xe7, 0x50, 0xda, 0xad, 0xc6, + 0x61, 0x1f, 0x62, 0x67, 0x07, 0xbb, 0x6c, 0x87, 0x2e, 0x79, 0xc9, 0x04, + 0x67, 0xd4, 0xb7, 0xb1, 0xb4, 0xf4, 0xb8, 0x63, 0x65, 0x65, 0x46, 0xb5, + 0xf3, 0xfc, 0xfc, 0x1d, 0x1d, 0x8d, 0x08, 0x3a, 0xa7, 0xf8, 0x70, 0x65, + 0xad, 0xda, 0x04, 0xc7, 0x94, 0x32, 0x55, 0xd0, 0x18, 0x9a, 0xb4, 0x97, + 0xe7, 0x98, 0x8f, 0x0c, 0x88, 0x1d, 0x58, 0xa0, 0xc0, 0x4a, 0xaf, 0xb8, + 0xad, 0xbf, 0x7d, 0x66, 0x49, 0x99, 0x8b, 0x5f, 0x61, 0xc2, 0xb6, 0x9b, + 0xf5, 0xf3, 0x0c, 0xe4, 0x41, 0x18, 0x47, 0xe7, 0xda, 0xb8, 0x79, 0xc3, + 0xdf, 0x3e, 0x72, 0x8d, 0xca, 0xd1, 0x66, 0x82, 0x94, 0xfe, 0xf7, 0x19, + 0x44, 0xed, 0x19, 0x67, 0xf8, 0x03, 0x3b, 0xb6, 0x00, 0x58, 0xb2, 0x83, + 0x05, 0x32, 0x90, 0x4f, 0x10, 0xd4, 0xc6, 0xe9, 0x66, 0x85, 0xb2, 0xae, + 0xe3, 0x75, 0xd4, 0xc5, 0xa3, 0x5b, 0x5b, 0x19, 0xf7, 0xa7, 0x32, 0xe3, + 0x1f, 0x3f, 0x82, 0x3f, 0x91, 0x89, 0x77, 0xcf, 0xcd, 0x61, 0xf3, 0x7b, + 0xde, 0xf8, 0xc7, 0xc4, 0xa0, 0xf0, 0xf1, 0xf3, 0x1b, 0x5a, 0x5b, 0x23, + 0x17, 0x29, 0x45, 0x94, 0xc8, 0xe7, 0xe4, 0xe7, 0xe6, 0x82, 0xd2, 0xd2, + 0xd2, 0x9a, 0x3d, 0xae, 0x29, 0xe5, 0x72, 0x04, 0x62, 0x9a, 0x9b, 0xb9, + 0x7e, 0x98, 0x9a, 0x06, 0x16, 0x5b, 0x39, 0x73, 0xc1, 0x82, 0x34, 0xd2, + 0x32, 0x8c, 0x64, 0x44, 0xe5, 0xa3, 0x09, 0x56, 0xa4, 0xb7, 0x67, 0xec, + 0x2d, 0xc5, 0x51, 0x05, 0xd6, 0x9b, 0x91, 0x16, 0xce, 0xf8, 0x68, 0xc8, + 0x8a, 0xba, 0x8d, 0xd2, 0xd6, 0xa0, 0x64, 0xd6, 0xf3, 0x0e, 0x13, 0x09, + 0x92, 0x3a, 0x86, 0xb6, 0x1f, 0x91, 0x4c, 0xfe, 0xa4, 0x1a, 0xe5, 0xee, + 0x78, 0x1a, 0x8a, 0xbe, 0x1b, 0x78, 0x33, 0x99, 0x50, 0xd3, 0x8d, 0x45, + 0xd3, 0x66, 0x54, 0x29, 0x13, 0xf1, 0xc5, 0x0e, 0x99, 0xad, 0xbf, 0x84, + 0xee, 0x33, 0x2a, 0xd1, 0xf2, 0x19, 0xd7, 0x8e, 0xc9, 0x39, 0xb4, 0xd8, + 0x94, 0x7c, 0x2f, 0x4a, 0xb9, 0x4d, 0x6e, 0x95, 0x30, 0xd7, 0xfa, 0x68, + 0x66, 0x10, 0x48, 0xa7, 0x67, 0x17, 0xf1, 0x25, 0x69, 0xe4, 0xa6, 0x85, + 0x4d, 0x97, 0x0b, 0xe2, 0x67, 0xb9, 0xae, 0x2b, 0x52, 0xcc, 0xc3, 0xc1, + 0xf4, 0x14, 0x01, 0x3f, 0xef, 0x73, 0x81, 0x7e, 0x1c, 0xe8, 0x82, 0x2d, + 0x1c, 0xb6, 0xfa, 0xab, 0x63, 0x0b, 0xa4, 0x5b, 0x7e, 0xce, 0xe6, 0x41, + 0xcb, 0x31, 0x97, 0xdb, 0x2e, 0x43, 0xa4, 0x98, 0xaa, 0xfe, 0x70, 0xa3, + 0xcd, 0x3f, 0x1c, 0x9f, 0xe7, 0xbb, 0x10, 0xa1, 0x2f, 0xfe, 0x21, 0x21, + 0x21, 0x23, 0xa9, 0x0b, 0x38, 0x11, 0xa2, 0x81, 0xbf, 0x7f, 0x53, 0x93, + 0x93, 0x93, 0x7f, 0xa1, 0xa1, 0x41, 0x54, 0xaf, 0xd2, 0xe9, 0x89, 0x21, + 0xe0, 0x54, 0xd0, 0xd1, 0xd1, 0x39, 0xf5, 0x4a, 0x06, 0x92, 0xcc, 0x96, + 0x8f, 0x06, 0x7b, 0x7f, 0x06, 0x69, 0x25, 0x3d, 0x0e, 0x79, 0x88, 0x9a, + 0xd5, 0x19, 0x18, 0xc3, 0x8b, 0x46, 0xca, 0xdb, 0x64, 0x1d, 0x4d, 0xa8, + 0xdd, 0xb3, 0xb9, 0xe8, 0x53, 0xa9, 0x70, 0xa1, 0x0e, 0x42, 0xd8, 0x5a, + 0x50, 0xca, 0xab, 0xc9, 0x48, 0x90, 0x74, 0x36, 0x43, 0xfa, 0x42, 0xf4, + 0xdf, 0xae, 0x7d, 0xcd, 0x8f, 0x3b, 0x6d, 0xf0, 0x7c, 0x53, 0xb9, 0xf8, + 0xb3, 0x25, 0x52, 0x9a, 0x4e, 0x80, 0xf1, 0x7e, 0xf5, 0x76, 0x9b, 0x3e, + 0xea, 0x97, 0xea, 0x5c, 0xc9, 0x53, 0xbc, 0x0c, 0x9b, 0xb7, 0xe9, 0xc5, + 0xc5, 0x6a, 0x75, 0xe1, 0x9e, 0x22, 0x2a, 0x4f, 0xa5, 0xb8, 0xc9, 0x60, + 0xa0, 0xb0, 0x26, 0x77, 0x0c, 0xeb, 0xb2, 0xf8, 0x03, 0x7a, 0x93, 0xa4, + 0x4c, 0xde, 0x98, 0xfc, 0xd5, 0xae, 0x53, 0x32, 0x32, 0xf0, 0xc9, 0xf2, + 0xdd, 0x70, 0x65, 0x88, 0x57, 0xd1, 0x92, 0xf1, 0x57, 0x3e, 0x2f, 0x84, + 0x06, 0x92, 0x7e, 0xf2, 0x7d, 0x7a, 0xd5, 0x27, 0xe4, 0x76, 0xc2, 0x7e, + 0x0c, 0x99, 0x23, 0x50, 0x32, 0x33, 0x33, 0xb3, 0x5e, 0xef, 0xfc, 0x6c, + 0x68, 0x68, 0xc8, 0xe3, 0xc4, 0x4c, 0x8b, 0x85, 0x28, 0x2a, 0x21, 0x61, + 0x3c, 0x91, 0xcd, 0xff, 0xb0, 0x1d, 0x27, 0xf8, 0x33, 0x31, 0x51, 0x65, + 0x57, 0x07, 0x35, 0x23, 0x26, 0xd7, 0x35, 0x3b, 0x95, 0xd3, 0x06, 0x9a, + 0x6f, 0x45, 0x6b, 0xd6, 0x93, 0x31, 0x4d, 0x27, 0x76, 0x26, 0xde, 0xad, + 0xd6, 0x62, 0xbf, 0xc7, 0xf1, 0xab, 0xdd, 0x8a, 0x8c, 0xbf, 0x13, 0x58, + 0x88, 0x2e, 0x8a, 0xc2, 0xbe, 0xf8, 0x30, 0xd0, 0xc1, 0xbf, 0x17, 0x16, + 0xa4, 0xe6, 0xc7, 0x07, 0x05, 0x25, 0x02, 0x69, 0xd9, 0x91, 0x52, 0xf5, + 0xa1, 0x7a, 0xb8, 0x04, 0x6e, 0xdb, 0x57, 0x95, 0x07, 0x8e, 0xf2, 0x5c, + 0x4b, 0xe2, 0xe2, 0xd9, 0x51, 0xe4, 0xbf, 0x0e, 0xf4, 0x6f, 0xf2, 0xc1, + 0x79, 0xc3, 0x40, 0xcb, 0xe6, 0x0d, 0x1b, 0x59, 0xe2, 0x6f, 0x28, 0xeb, + 0x10, 0xde, 0x63, 0xcb, 0xee, 0xdf, 0xc3, 0x99, 0x37, 0x90, 0xb9, 0x79, + 0x11, 0xbb, 0x21, 0x1f, 0x2f, 0xa0, 0x18, 0xae, 0x2e, 0xf7, 0x69, 0x28, + 0x90, 0x14, 0x69, 0x1e, 0xf7, 0x53, 0x74, 0xf6, 0xb7, 0x33, 0x36, 0x6d, + 0x88, 0x49, 0x89, 0x37, 0x5c, 0x6b, 0xd0, 0xe1, 0x0c, 0xc6, 0x11, 0xc7, + 0xb9, 0x1c, 0xcf, 0xf7, 0xac, 0xad, 0xe9, 0xed, 0x7b, 0x76, 0x84, 0x16, + 0x5b, 0xe8, 0xb4, 0xbb, 0x7f, 0x3a, 0x5e, 0xa8, 0x1e, 0xf2, 0x7b, 0x7f, + 0x0d, 0xcb, 0xcf, 0xcf, 0x97, 0xda, 0xc7, 0xbb, 0xf4, 0x78, 0x30, 0xb8, + 0x52, 0x68, 0x67, 0x2f, 0x4c, 0x11, 0xd7, 0x67, 0xfb, 0xe3, 0x78, 0x55, + 0xbb, 0xf5, 0x4f, 0x37, 0xbc, 0xfd, 0xb6, 0x66, 0xd9, 0x83, 0x24, 0xeb, + 0xf5, 0xe2, 0xf4, 0x8f, 0x26, 0xac, 0xb2, 0xf0, 0x39, 0x3b, 0x9b, 0xec, + 0x76, 0x6f, 0x03, 0xf5, 0x09, 0x8f, 0x3d, 0xac, 0x5b, 0x41, 0x4e, 0x92, + 0x47, 0x6f, 0x71, 0x8b, 0xce, 0x7e, 0x9c, 0x8f, 0x4f, 0x53, 0x35, 0x55, + 0xc3, 0x26, 0x42, 0x6b, 0x6f, 0x8d, 0x2f, 0x01, 0x7c, 0xb0, 0x67, 0xf7, + 0x92, 0x47, 0x99, 0x85, 0xe3, 0xd5, 0x14, 0x05, 0x72, 0x42, 0x93, 0xbf, + 0xe1, 0xce, 0xca, 0x82, 0x23, 0xa2, 0x7f, 0x75, 0x09, 0x81, 0xa9, 0x6c, + 0xb4, 0x50, 0xca, 0x9d, 0xde, 0xad, 0x11, 0x1d, 0x38, 0xb4, 0x67, 0xca, + 0x89, 0xb3, 0xe6, 0x29, 0xac, 0x03, 0x3d, 0xa2, 0x9c, 0xc1, 0xa8, 0xd7, + 0xa8, 0x76, 0xb2, 0xcd, 0xcd, 0xae, 0x42, 0xaf, 0x03, 0xff, 0x33, 0x8f, + 0xf3, 0x64, 0x8b, 0xde, 0x1c, 0x49, 0xbc, 0xa4, 0xfd, 0xf1, 0x3c, 0xfd, + 0xcb, 0xcd, 0x8c, 0xfc, 0x62, 0x93, 0x1d, 0x71, 0xe1, 0x74, 0xa4, 0x27, + 0x1a, 0xe2, 0x69, 0x70, 0xda, 0x76, 0xef, 0xe6, 0x74, 0x6f, 0xd5, 0xfc, + 0x31, 0x2b, 0x72, 0xd0, 0x07, 0x16, 0xa5, 0xac, 0x9f, 0x97, 0x5e, 0xb5, + 0x6e, 0x6e, 0xc8, 0xd3, 0x6e, 0x1c, 0x2d, 0x56, 0xcc, 0x5b, 0x2d, 0xe0, + 0x22, 0x52, 0xc4, 0xa0, 0x08, 0x9e, 0x0f, 0x9d, 0x87, 0xfd, 0x4d, 0x8a, + 0x57, 0xda, 0xb8, 0xee, 0xd8, 0x93, 0x2e, 0x62, 0x5e, 0x3f, 0x90, 0x65, + 0x16, 0x29, 0x08, 0x05, 0x3b, 0x8b, 0x24, 0x08, 0x7f, 0x39, 0x20, 0x4f, + 0x1c, 0xc6, 0x10, 0x54, 0xa1, 0x71, 0xda, 0x03, 0xb1, 0xb0, 0x5b, 0xa1, + 0x4f, 0x36, 0xb2, 0xe3, 0x74, 0xf0, 0xe2, 0x13, 0x55, 0xd1, 0x1f, 0x9d, + 0xce, 0x96, 0x14, 0x5a, 0xbc, 0x5c, 0xfc, 0x33, 0x7c, 0xb9, 0x5a, 0x40, + 0x50, 0x89, 0x5f, 0x46, 0x06, 0xc1, 0xa3, 0xa2, 0x0e, 0xc6, 0x09, 0xbe, + 0xc1, 0x13, 0x13, 0xe7, 0x78, 0x4e, 0x95, 0x73, 0xfc, 0x30, 0x31, 0x31, + 0x9c, 0xaf, 0xd0, 0x5c, 0xec, 0xf2, 0xf3, 0x0b, 0x31, 0xa3, 0xc3, 0x09, + 0x41, 0x91, 0x5e, 0x17, 0xae, 0x66, 0x38, 0x65, 0xd3, 0xe2, 0xfd, 0xca, + 0x8e, 0xc9, 0x7b, 0x9f, 0xd3, 0xbb, 0xc9, 0xaa, 0x4e, 0x92, 0x52, 0x5e, + 0x52, 0x16, 0x47, 0xb8, 0x08, 0x25, 0xbd, 0x4e, 0x6c, 0x66, 0x4f, 0x75, + 0xf3, 0x87, 0x09, 0x39, 0x28, 0x69, 0xfd, 0x7c, 0xe0, 0x6d, 0x3b, 0x65, + 0x44, 0xf2, 0x91, 0xdb, 0x5f, 0x0c, 0xf7, 0x4b, 0xd6, 0x4a, 0x29, 0x66, + 0xbd, 0xdc, 0xaa, 0x16, 0xeb, 0x27, 0x78, 0x14, 0x90, 0xdf, 0x7b, 0xd8, + 0x7f, 0x23, 0xad, 0x8b, 0x8a, 0x0c, 0x7e, 0xae, 0x81, 0xc5, 0x4e, 0x83, + 0x90, 0x52, 0x98, 0xa0, 0x9a, 0x46, 0xb6, 0xbe, 0x1a, 0xdf, 0xd5, 0x8b, + 0x61, 0x2f, 0x63, 0x66, 0x1b, 0x67, 0xbf, 0x45, 0x8d, 0xf4, 0x85, 0x8c, + 0x80, 0x9f, 0xb4, 0x89, 0x1a, 0x97, 0xab, 0xb6, 0x2f, 0x1e, 0x3b, 0x22, + 0x45, 0x13, 0x30, 0x90, 0x10, 0x83, 0x31, 0x04, 0x61, 0xb2, 0x19, 0x1c, + 0x86, 0x8f, 0x57, 0xbb, 0xb7, 0x47, 0x7a, 0xd5, 0x28, 0x22, 0x79, 0xe8, + 0x7d, 0xa1, 0x28, 0xdf, 0xb4, 0xb4, 0xf0, 0xcf, 0x56, 0xdb, 0x4a, 0x92, + 0x7b, 0x07, 0x98, 0xba, 0x1f, 0xcb, 0xef, 0x7f, 0xa6, 0xa7, 0x05, 0x71, + 0x54, 0x66, 0x5a, 0x66, 0xed, 0x99, 0xda, 0x5a, 0x46, 0xff, 0x94, 0xf3, + 0x05, 0x66, 0x43, 0x4c, 0x9d, 0xfa, 0x59, 0x99, 0x8b, 0x47, 0x94, 0x47, + 0x3a, 0x7c, 0xba, 0x21, 0xfa, 0xc1, 0xc2, 0xb2, 0x41, 0x0c, 0x8f, 0x98, + 0xe2, 0x01, 0x90, 0x88, 0xaa, 0x95, 0x58, 0x61, 0xb5, 0xb3, 0x63, 0xe7, + 0x6f, 0x45, 0xfe, 0xf9, 0x93, 0xeb, 0xcb, 0x9e, 0x7b, 0x68, 0x46, 0x97, + 0xb2, 0x4a, 0xaa, 0xb1, 0xb9, 0xaa, 0xc8, 0xd7, 0x9c, 0x00, 0x6d, 0x63, + 0x8c, 0xa7, 0xcb, 0x62, 0x98, 0x9a, 0xe5, 0xac, 0xd2, 0xa6, 0x94, 0xa0, + 0x42, 0x98, 0x03, 0x3c, 0xe8, 0x6c, 0xb9, 0x1f, 0x72, 0x16, 0xd0, 0x19, + 0x0e, 0x7f, 0x8c, 0x9c, 0x27, 0x44, 0xd5, 0xc1, 0x5b, 0x46, 0xd1, 0x55, + 0x03, 0x8e, 0x52, 0xb3, 0xeb, 0xbb, 0xf5, 0xaa, 0xc5, 0xce, 0x06, 0xe4, + 0xc9, 0xf0, 0x70, 0xba, 0x28, 0x95, 0xc3, 0x06, 0xdf, 0xda, 0x9a, 0x86, + 0x5e, 0xc4, 0xac, 0xa6, 0xdd, 0xfd, 0x12, 0x52, 0xbb, 0xc9, 0x76, 0xa0, + 0x4a, 0xb7, 0x8d, 0x06, 0x7a, 0x32, 0x2d, 0x0d, 0xbe, 0x76, 0x73, 0xc6, + 0xed, 0xd3, 0x6f, 0xc3, 0xdb, 0xc6, 0xe7, 0xb8, 0x2d, 0x66, 0xaf, 0x47, + 0x71, 0x2c, 0x9c, 0xa8, 0xb9, 0x1d, 0x40, 0x40, 0xb6, 0x47, 0x43, 0x94, + 0x0d, 0x49, 0x2b, 0x34, 0x33, 0x83, 0x7e, 0x15, 0x2b, 0x6a, 0x90, 0x8b, + 0x68, 0x99, 0x32, 0xd8, 0xf2, 0xbb, 0x07, 0xbe, 0x04, 0x92, 0xb2, 0xd5, + 0xd5, 0x89, 0x3b, 0xf1, 0x5a, 0xd5, 0xdb, 0x6c, 0x97, 0x39, 0xd8, 0xfa, + 0xb8, 0x00, 0x4a, 0x6d, 0x74, 0x15, 0xd8, 0x20, 0x29, 0x35, 0xae, 0x32, + 0xbc, 0x68, 0x9d, 0x02, 0x21, 0x65, 0xb2, 0x85, 0x50, 0x69, 0x27, 0x6e, + 0x3e, 0x0d, 0x68, 0x94, 0x79, 0xbd, 0x7d, 0xcb, 0x5a, 0xd6, 0xee, 0x55, + 0xbf, 0xac, 0x90, 0x83, 0x7f, 0x44, 0x2d, 0x28, 0x41, 0xe2, 0xa6, 0xe7, + 0x77, 0x00, 0xbf, 0x81, 0xa1, 0x69, 0x3e, 0x67, 0x16, 0x86, 0xf2, 0x34, + 0xf3, 0x7d, 0x14, 0xf1, 0xa7, 0x9c, 0x44, 0xb5, 0x4d, 0xcd, 0xf5, 0x4e, + 0x9f, 0x5a, 0xe3, 0x21, 0x54, 0x36, 0xbb, 0x35, 0x1d, 0xb4, 0x74, 0x0b, + 0xb4, 0x5a, 0x8d, 0xe8, 0x34, 0x56, 0x33, 0x23, 0xa0, 0x9d, 0x2d, 0x1d, + 0x03, 0x3e, 0x11, 0x77, 0x55, 0xe8, 0x82, 0x18, 0xdd, 0xc6, 0x1d, 0xef, + 0x89, 0x07, 0x28, 0x0c, 0xff, 0x46, 0x8e, 0xff, 0x47, 0xb7, 0xb0, 0x34, + 0x5e, 0x2d, 0x2b, 0x6d, 0xad, 0xf9, 0x68, 0x98, 0xa4, 0xff, 0xf7, 0x87, + 0x23, 0xcc, 0x5f, 0xd1, 0xb5, 0x1e, 0xe0, 0x95, 0xb9, 0xdc, 0x6e, 0x89, + 0x22, 0x23, 0x07, 0x92, 0x92, 0xed, 0x76, 0x1d, 0xb9, 0x2f, 0x5c, 0xdd, + 0x7a, 0xfa, 0x0d, 0x0d, 0x0f, 0x56, 0x75, 0xdb, 0x1c, 0x10, 0x3f, 0x58, + 0x90, 0xe2, 0x58, 0x2a, 0x68, 0x65, 0xc9, 0x7a, 0x74, 0x55, 0xca, 0xe4, + 0x4c, 0xb4, 0xd2, 0x56, 0xc4, 0xfc, 0xea, 0x23, 0xc6, 0x1f, 0xcd, 0x8e, + 0x0f, 0xde, 0x77, 0xff, 0x94, 0x2c, 0x46, 0xd8, 0x84, 0x96, 0x89, 0x0c, + 0x34, 0x82, 0xbc, 0xdc, 0x7a, 0xc2, 0x94, 0xc3, 0x2c, 0x32, 0xa9, 0x2a, + 0xe9, 0x19, 0x56, 0xbd, 0xc3, 0x29, 0xac, 0x9a, 0xd4, 0xb9, 0x4c, 0x1a, + 0x2d, 0xe7, 0x10, 0x09, 0x38, 0xac, 0xbb, 0x37, 0x7a, 0x82, 0x50, 0xe6, + 0x7d, 0x74, 0xb4, 0xc1, 0xa1, 0xc2, 0x2a, 0x2a, 0x58, 0xbd, 0x7d, 0x7d, + 0xf1, 0xbf, 0x94, 0xb4, 0xd4, 0x07, 0x56, 0x1b, 0xb8, 0x5d, 0xfd, 0xea, + 0xc0, 0xe2, 0xde, 0xd9, 0xe2, 0xc7, 0x02, 0xd2, 0xde, 0x11, 0x87, 0x51, + 0x1c, 0x2a, 0x92, 0xc7, 0xc7, 0x38, 0x1b, 0x51, 0xd5, 0x82, 0x3e, 0xb8, + 0xde, 0xd9, 0x9e, 0x3e, 0xfe, 0xbf, 0x17, 0xf7, 0x35, 0xee, 0x6e, 0xab, + 0x25, 0x65, 0xe4, 0xaa, 0xe7, 0x04, 0xfa, 0x9e, 0xdd, 0x86, 0x86, 0xce, + 0x63, 0x21, 0x72, 0x86, 0x7c, 0xae, 0x77, 0xf0, 0xbf, 0xfc, 0x92, 0x9c, + 0x72, 0xdb, 0x32, 0xc2, 0x2a, 0x7d, 0x5b, 0x77, 0x3a, 0x87, 0x72, 0x1c, + 0x0f, 0x44, 0x82, 0x0f, 0xa6, 0xf9, 0xe2, 0x76, 0x10, 0x2c, 0x1e, 0x10, + 0xf1, 0x1d, 0x8d, 0x43, 0x96, 0xd6, 0x74, 0xc6, 0x79, 0xb0, 0x5a, 0xca, + 0x64, 0x8f, 0x5c, 0x68, 0x6a, 0x65, 0x70, 0x24, 0xf3, 0xc9, 0xe8, 0x0d, + 0x4b, 0x86, 0x60, 0x15, 0xad, 0xd7, 0x53, 0x92, 0xbf, 0x1c, 0x31, 0x14, + 0x22, 0x36, 0xb3, 0x23, 0xb2, 0xe8, 0xd8, 0x4d, 0x88, 0x2e, 0xbe, 0x74, + 0x87, 0x0e, 0x07, 0x09, 0x93, 0x52, 0xa6, 0xbb, 0x27, 0x08, 0x6e, 0xf3, + 0xfc, 0x7c, 0xdd, 0x3c, 0x9a, 0x5b, 0xc1, 0xd1, 0x6f, 0xa5, 0x42, 0x93, + 0x95, 0x1a, 0x0b, 0x31, 0x93, 0xdb, 0x49, 0x9c, 0x62, 0x62, 0x98, 0x56, + 0x34, 0x5e, 0x32, 0xd0, 0x16, 0x42, 0x00, 0xff, 0xd5, 0xa7, 0x92, 0x4e, + 0xe6, 0xd3, 0xc1, 0x3a, 0x2c, 0x6e, 0xd5, 0xaa, 0xfa, 0x73, 0x93, 0x8c, + 0x67, 0x5a, 0x40, 0x73, 0xbf, 0xca, 0xcd, 0xc9, 0x16, 0x1a, 0x6a, 0x06, + 0x4a, 0xad, 0x68, 0x68, 0x5f, 0x49, 0xb5, 0xc1, 0x65, 0xfa, 0xe9, 0x2e, + 0xe2, 0x7c, 0x22, 0x06, 0x06, 0x46, 0x60, 0x6e, 0xee, 0x97, 0x1f, 0x66, + 0x66, 0xea, 0xd4, 0xb9, 0xd7, 0x07, 0x4b, 0x48, 0x3a, 0x6d, 0xcf, 0xf0, + 0x3e, 0x81, 0xbc, 0x96, 0x03, 0xbf, 0x9d, 0xb8, 0x09, 0xc9, 0x8b, 0x4c, + 0x49, 0x39, 0xce, 0x6e, 0x55, 0xa1, 0x79, 0x3f, 0xe7, 0x36, 0xcd, 0x7a, + 0x18, 0x42, 0xe6, 0x21, 0xc7, 0xec, 0x63, 0x06, 0x4f, 0xfe, 0xd8, 0xbc, + 0xe4, 0x69, 0x4c, 0x1e, 0x26, 0x3a, 0x85, 0x15, 0x0d, 0x10, 0xfa, 0xce, + 0x70, 0xb3, 0x18, 0x9e, 0x9d, 0xca, 0x6c, 0x0a, 0x92, 0x71, 0x5e, 0x34, + 0x6b, 0x2f, 0xce, 0x6c, 0x73, 0x44, 0x43, 0x52, 0xb7, 0x81, 0x91, 0x4d, + 0x69, 0xf5, 0xe8, 0xeb, 0xed, 0xad, 0xf1, 0x79, 0x76, 0x6d, 0x6e, 0x6e, + 0x3e, 0x50, 0x64, 0x5d, 0x2d, 0x50, 0xa1, 0x61, 0xb6, 0x59, 0x66, 0x7b, + 0xb9, 0xfb, 0x67, 0x47, 0x83, 0x07, 0x63, 0x30, 0xd0, 0x3e, 0x0c, 0x9e, + 0x2e, 0x89, 0x1a, 0x3c, 0xa6, 0x2c, 0xfe, 0x61, 0xb0, 0xb7, 0x65, 0xf7, + 0x33, 0x3e, 0xab, 0x9c, 0xd2, 0xce, 0xd6, 0x0e, 0x85, 0x80, 0xd6, 0x89, + 0x4f, 0x5a, 0xb2, 0x94, 0x03, 0x05, 0x1d, 0x24, 0xf0, 0x74, 0x40, 0x56, + 0xa1, 0xdb, 0x86, 0x03, 0xa8, 0xe3, 0xce, 0x70, 0x02, 0x98, 0xd5, 0x14, + 0x19, 0x11, 0x09, 0x69, 0x6e, 0x0f, 0xd0, 0xe4, 0xcf, 0xa3, 0xfb, 0xd1, + 0x0b, 0x23, 0x29, 0x95, 0x8b, 0xcd, 0xe4, 0xd1, 0xcf, 0x06, 0x14, 0x60, + 0x10, 0x16, 0xc5, 0xd8, 0xc5, 0xfd, 0xfb, 0xca, 0xe5, 0x5a, 0x47, 0xdc, + 0xd1, 0x1a, 0x51, 0x9c, 0x90, 0x3b, 0x0c, 0x77, 0x1e, 0x26, 0x3e, 0x9d, + 0xb8, 0xf8, 0x9b, 0x1a, 0x9b, 0x2c, 0xbd, 0x1a, 0x35, 0x46, 0x13, 0xd4, + 0xaf, 0xe4, 0x41, 0x48, 0x32, 0x19, 0xbc, 0x39, 0x5c, 0x5a, 0x5c, 0x39, + 0x31, 0x8d, 0x85, 0xbb, 0x0d, 0x8b, 0x61, 0x5d, 0x2d, 0x5c, 0x00, 0xe2, + 0x7a, 0xf3, 0xe7, 0xfe, 0xcd, 0xca, 0x25, 0x70, 0x70, 0x70, 0x34, 0x3b, + 0xee, 0x46, 0xf6, 0x88, 0x57, 0x59, 0x61, 0xe2, 0x44, 0x85, 0x5c, 0x5c, + 0xd8, 0xaf, 0x34, 0x3b, 0x40, 0x39, 0x38, 0x38, 0xd0, 0x78, 0xec, 0x8c, + 0x87, 0x99, 0xaf, 0x4e, 0x23, 0x54, 0xc5, 0xa6, 0xbf, 0x12, 0x68, 0xa4, + 0xe2, 0x15, 0x74, 0xc4, 0xf1, 0x02, 0xab, 0x53, 0x76, 0x27, 0x56, 0x5a, + 0xa3, 0x11, 0x7d, 0x53, 0xa1, 0xf3, 0x1f, 0xb6, 0xea, 0xbd, 0xe8, 0xe1, + 0x42, 0x35, 0x71, 0xbf, 0x11, 0x33, 0x83, 0x5e, 0x3b, 0x7c, 0x7a, 0xb1, + 0xa1, 0xb1, 0x71, 0x90, 0xed, 0x6a, 0x6b, 0x40, 0x3e, 0x75, 0x26, 0xbf, + 0x97, 0x9a, 0x8d, 0xad, 0xf5, 0x0a, 0x52, 0xcd, 0x92, 0xb5, 0xb3, 0xf5, + 0x71, 0x5e, 0x7c, 0xb6, 0x49, 0x2d, 0x20, 0x45, 0xc3, 0xd2, 0x4d, 0xfa, + 0x49, 0x61, 0x49, 0x04, 0x66, 0x26, 0xfc, 0xef, 0x51, 0xc5, 0x4e, 0xe5, + 0xd5, 0xe4, 0xa2, 0x5f, 0x66, 0x21, 0x4f, 0x1b, 0x43, 0x48, 0xd1, 0x8f, + 0x10, 0x88, 0x26, 0x1a, 0x52, 0x54, 0x9e, 0xe8, 0x00, 0xa2, 0x4b, 0x86, + 0x62, 0x71, 0xf2, 0xab, 0x56, 0x5b, 0x7c, 0xdf, 0x76, 0x6c, 0x17, 0x74, + 0x60, 0xb2, 0xae, 0xac, 0xff, 0xd7, 0xa8, 0xa2, 0xcc, 0xa0, 0xd3, 0x16, + 0x77, 0x48, 0xec, 0x17, 0xb3, 0xf2, 0x32, 0x5d, 0x66, 0x49, 0x88, 0x0a, + 0xf7, 0xaf, 0xd1, 0x26, 0x28, 0x2d, 0xcd, 0xf7, 0xfc, 0xfa, 0x18, 0x93, + 0x28, 0x2e, 0x2c, 0x08, 0x0e, 0x2d, 0x5f, 0x3e, 0x47, 0x80, 0x26, 0x4d, + 0xa4, 0xb4, 0xff, 0xaa, 0xda, 0x8d, 0x54, 0x3a, 0xe8, 0xcc, 0xa1, 0xfa, + 0xf2, 0xd6, 0x79, 0xa0, 0x7b, 0x52, 0xae, 0xc1, 0xd7, 0x6e, 0x20, 0x12, + 0x9b, 0xcb, 0xfb, 0x81, 0x89, 0x1c, 0x03, 0x21, 0x99, 0x51, 0x3f, 0xd6, + 0xf5, 0x74, 0xd9, 0x70, 0x2c, 0x95, 0x59, 0x52, 0x4e, 0xae, 0xca, 0xf9, + 0x6d, 0xbe, 0x43, 0x22, 0x5e, 0x91, 0x01, 0x5d, 0x1e, 0x93, 0x3a, 0x52, + 0xe4, 0xa7, 0x1f, 0xc1, 0x5c, 0xaa, 0x61, 0x64, 0xc3, 0x4c, 0x4d, 0x16, + 0x90, 0x4d, 0xe6, 0x83, 0x60, 0xd8, 0x90, 0xa6, 0x7b, 0x16, 0x08, 0x83, + 0x4e, 0x29, 0x4a, 0x2f, 0x87, 0x48, 0xc3, 0x48, 0x6d, 0x05, 0xac, 0x90, + 0x78, 0xa8, 0xc0, 0x5a, 0x93, 0x5d, 0x42, 0xae, 0x45, 0xc0, 0xa5, 0xf3, + 0x83, 0x28, 0x20, 0x0c, 0xfd, 0x88, 0x3a, 0xc2, 0x1f, 0xf5, 0x6d, 0xe9, + 0x31, 0xa1, 0x55, 0x1d, 0xb5, 0x5e, 0x81, 0xa1, 0xcd, 0xe4, 0x7c, 0x30, + 0x69, 0xb9, 0x66, 0x9b, 0x09, 0x0f, 0x0d, 0x69, 0xbd, 0xda, 0xaa, 0x7a, + 0x1a, 0x25, 0x03, 0x58, 0x90, 0xa8, 0xce, 0x27, 0x3c, 0xa5, 0xb4, 0x3d, + 0xbd, 0xfd, 0xcd, 0xd7, 0xd6, 0x85, 0xa7, 0xac, 0x16, 0xa7, 0xfd, 0xfc, + 0xdf, 0xbf, 0xe1, 0xdf, 0xdf, 0x9e, 0x19, 0x4f, 0x4e, 0x4f, 0xf3, 0x54, + 0x68, 0x6a, 0xed, 0xd6, 0x05, 0xac, 0xd7, 0xda, 0x5b, 0xa6, 0x1f, 0xa5, + 0x28, 0x62, 0xde, 0xab, 0x24, 0x2c, 0x2a, 0x8c, 0x35, 0xb5, 0xd8, 0xea, + 0xd4, 0x5e, 0xd3, 0x0c, 0x77, 0x0c, 0xb5, 0x34, 0x13, 0xff, 0x7f, 0x3c, + 0x50, 0x61, 0x33, 0xcb, 0x82, 0x94, 0xa6, 0x7d, 0x36, 0x5f, 0xde, 0x31, + 0xfd, 0xf7, 0xc0, 0x97, 0x1e, 0x1a, 0x2d, 0xf6, 0x34, 0x02, 0xaf, 0x06, + 0x7c, 0xd0, 0xe2, 0xb7, 0x39, 0xf2, 0x7a, 0xd8, 0x1f, 0xc1, 0x54, 0xfb, + 0xbe, 0x74, 0x88, 0xf0, 0x4e, 0x03, 0x8b, 0x19, 0x0d, 0x66, 0x16, 0x91, + 0xd7, 0x3a, 0x24, 0xe6, 0xe4, 0xe4, 0x04, 0x5a, 0x06, 0x76, 0x7e, 0xbe, + 0x48, 0xfc, 0xf4, 0x6f, 0x5f, 0xc9, 0x62, 0xf3, 0x75, 0xee, 0xa0, 0xd5, + 0x53, 0x83, 0xc3, 0xb7, 0xf7, 0xec, 0x80, 0x06, 0xcf, 0xfd, 0xa7, 0xdb, + 0x63, 0x78, 0x24, 0xa4, 0x20, 0x0d, 0xba, 0xc1, 0x0e, 0xaf, 0xfb, 0x8d, + 0x93, 0x97, 0x3d, 0xb6, 0x56, 0x3b, 0xbf, 0x47, 0xb8, 0x96, 0xc7, 0x10, + 0xbb, 0xcc, 0x7b, 0xca, 0xf4, 0x7f, 0x49, 0x6f, 0xab, 0x16, 0x5a, 0xb3, + 0xe5, 0x7f, 0x91, 0x30, 0xe0, 0x4d, 0x00, 0xc2, 0x31, 0x98, 0x6c, 0x6e, + 0xdd, 0xfb, 0x46, 0x7d, 0xc2, 0x14, 0x9d, 0x1f, 0x5c, 0x82, 0x1d, 0x69, + 0xd6, 0x04, 0x8a, 0xc7, 0x05, 0x01, 0x7e, 0x7e, 0x23, 0xa5, 0x01, 0x89, + 0xa9, 0x46, 0xfd, 0x67, 0xa7, 0xaa, 0xca, 0xb6, 0xf3, 0xce, 0xe7, 0x8a, + 0xa5, 0x2b, 0x89, 0x10, 0x3e, 0x33, 0x34, 0x34, 0xb4, 0x97, 0x97, 0xeb, + 0x09, 0xcf, 0xe9, 0x11, 0x7b, 0x78, 0x64, 0xe4, 0xfe, 0xcb, 0xed, 0xa1, + 0x9e, 0xfd, 0x14, 0x5f, 0x88, 0xe7, 0xd7, 0x8b, 0x16, 0x29, 0x9e, 0xc4, + 0x39, 0xe4, 0xc8, 0xfc, 0x8b, 0xdd, 0xc0, 0xaf, 0x60, 0x6c, 0x22, 0xa5, + 0xf2, 0xfb, 0x44, 0x29, 0x8a, 0x50, 0x34, 0xe2, 0xd8, 0x38, 0x81, 0xa7, + 0xdf, 0xe2, 0xd7, 0x51, 0x62, 0x18, 0xfd, 0x7c, 0x5e, 0x79, 0x11, 0x91, + 0x96, 0x1a, 0x9a, 0x89, 0xa7, 0x8b, 0x54, 0x54, 0xcc, 0x32, 0xd0, 0x95, + 0x22, 0xc8, 0x3c, 0x3d, 0x06, 0x9b, 0xf6, 0xed, 0xc1, 0xdf, 0xbf, 0x13, + 0x79, 0x89, 0xe5, 0x7b, 0xbd, 0x33, 0x45, 0xff, 0xbe, 0x3f, 0x8e, 0x35, + 0x17, 0x20, 0x62, 0x78, 0x30, 0x39, 0x85, 0x74, 0xf7, 0x02, 0xab, 0x05, + 0xbb, 0x2b, 0xd6, 0x82, 0xcb, 0x39, 0xce, 0x2b, 0xeb, 0xcd, 0x87, 0xd3, + 0xd9, 0xad, 0x0c, 0xcc, 0xd4, 0x9f, 0xc5, 0x29, 0x62, 0xe2, 0xbb, 0xbb, + 0x85, 0xa2, 0x09, 0xb9, 0x95, 0xd8, 0x8b, 0x2d, 0x60, 0xad, 0x1a, 0x5f, + 0x4a, 0x6b, 0x8f, 0xb3, 0xfa, 0x4c, 0x8d, 0x2f, 0x2b, 0x98, 0x0f, 0x4a, + 0x84, 0x69, 0xe7, 0x56, 0xdb, 0xdc, 0xb6, 0x07, 0xa2, 0xd2, 0xf1, 0x8e, + 0xa2, 0x38, 0x89, 0x66, 0x3d, 0x5f, 0xaf, 0xc2, 0x47, 0xa0, 0x25, 0x20, + 0xed, 0x59, 0xd9, 0x4f, 0xcb, 0xbb, 0x68, 0x24, 0x82, 0xc5, 0xe1, 0x98, + 0x0f, 0xa0, 0x83, 0xfa, 0xff, 0xfb, 0xed, 0xa4, 0x1d, 0x42, 0xfa, 0x56, + 0xac, 0x94, 0xc6, 0x8c, 0x4a, 0xed, 0xa0, 0x9b, 0x81, 0x8f, 0x74, 0xd1, + 0x93, 0x98, 0xb7, 0xd8, 0xb2, 0x49, 0xc6, 0xc5, 0xbd, 0x78, 0xa4, 0xd9, + 0x17, 0x99, 0xd9, 0xee, 0x2e, 0x4d, 0x0f, 0x3a, 0x63, 0xef, 0xf0, 0xbc, + 0x15, 0x11, 0x15, 0x0d, 0x26, 0x62, 0x63, 0xd1, 0x19, 0xc1, 0x77, 0x06, + 0xb9, 0x5f, 0xb2, 0x40, 0x49, 0xfc, 0xd5, 0x9b, 0x71, 0xe7, 0xe7, 0x88, + 0x0a, 0x79, 0x1f, 0xcf, 0xc8, 0x77, 0x20, 0x4b, 0x4d, 0xb7, 0xbf, 0x39, + 0x61, 0xc7, 0x8a, 0xe8, 0xb7, 0xcb, 0xd6, 0x40, 0x69, 0xf1, 0xb0, 0xe4, + 0xbe, 0x4c, 0x6c, 0x69, 0x69, 0xaa, 0x28, 0x6b, 0x81, 0x16, 0xb1, 0x21, + 0x01, 0x32, 0xac, 0x20, 0x93, 0xae, 0x02, 0xcf, 0xb0, 0xe0, 0x52, 0x23, + 0x83, 0xe3, 0x82, 0xf0, 0xd3, 0xbd, 0x2b, 0x19, 0xed, 0x00, 0x2f, 0xfc, + 0xdb, 0xbf, 0xce, 0xee, 0x9b, 0xa9, 0xd7, 0x9e, 0x5d, 0xfb, 0x32, 0x6d, + 0x11, 0xc6, 0xf0, 0x7e, 0xa5, 0x97, 0xa7, 0xfb, 0x43, 0x44, 0x47, 0x4c, + 0x4c, 0xcc, 0x97, 0xc7, 0xfd, 0x9c, 0x0d, 0x70, 0xee, 0xdf, 0xe5, 0x60, + 0xc3, 0x54, 0x44, 0x66, 0xa8, 0xb9, 0x4f, 0x38, 0x38, 0xb0, 0x44, 0xf2, + 0x1d, 0x5a, 0x2b, 0x67, 0x50, 0x66, 0x56, 0x0d, 0xe2, 0x1e, 0xee, 0x7c, + 0xa8, 0xf3, 0x0c, 0xd9, 0x01, 0x9f, 0xa0, 0x02, 0xf3, 0xa2, 0xf0, 0xf9, + 0xd9, 0xc6, 0xfd, 0xc7, 0xa7, 0x8f, 0x24, 0x28, 0x13, 0x32, 0x5f, 0xe8, + 0x81, 0x17, 0xab, 0x9c, 0x6a, 0x16, 0x34, 0x81, 0x47, 0x41, 0x0c, 0xc8, + 0xad, 0xbe, 0xad, 0xd2, 0x95, 0xd3, 0x06, 0x53, 0xfa, 0x91, 0x2b, 0x6c, + 0x35, 0x36, 0x36, 0xd5, 0xf6, 0xe3, 0x5e, 0x53, 0x91, 0xfd, 0xb7, 0x3e, + 0x93, 0x4b, 0x5b, 0xfa, 0xea, 0x70, 0x03, 0xa9, 0xd7, 0x5e, 0x91, 0xaa, + 0xf4, 0x72, 0x58, 0x92, 0xd3, 0x3b, 0x3f, 0x7f, 0xd1, 0x8e, 0xb0, 0x2c, + 0x52, 0xaa, 0xb2, 0x35, 0x99, 0xf7, 0x4d, 0xa3, 0xc5, 0x91, 0x82, 0x48, + 0xd0, 0x37, 0xda, 0xf7, 0xf5, 0x09, 0x80, 0x42, 0x22, 0x40, 0x52, 0x98, + 0xd8, 0xd9, 0x43, 0x6a, 0x6b, 0x99, 0xc5, 0xe3, 0x88, 0x74, 0xf3, 0xa6, + 0xa2, 0x4b, 0x4b, 0xbf, 0x7a, 0xde, 0x1c, 0xe4, 0xa9, 0x89, 0x31, 0x90, + 0x70, 0xa3, 0xe0, 0x56, 0x49, 0x90, 0xd4, 0xa3, 0x96, 0x58, 0x33, 0xa4, + 0x04, 0xc9, 0x9b, 0xc5, 0x85, 0x75, 0xa9, 0xd3, 0x7a, 0xd7, 0x3a, 0xe0, + 0x62, 0xcd, 0xed, 0x14, 0x2c, 0x24, 0x33, 0x7c, 0x6e, 0xaf, 0x27, 0xf4, + 0x1e, 0xae, 0xe1, 0x22, 0xb4, 0x53, 0x0e, 0x21, 0x2d, 0x3e, 0x9b, 0x72, + 0x85, 0x86, 0x04, 0xec, 0x31, 0x18, 0xba, 0x8a, 0x89, 0xc5, 0xa8, 0x83, + 0x0a, 0x47, 0xff, 0x01, 0xf9, 0x67, 0x29, 0x43, 0x3a, 0xbf, 0x36, 0xf7, + 0xe6, 0x3f, 0x93, 0x3a, 0x64, 0xca, 0xcf, 0x95, 0x34, 0x8e, 0x57, 0x88, + 0xb5, 0xcf, 0xdd, 0x69, 0x88, 0x8e, 0x12, 0x12, 0x12, 0x74, 0x3a, 0xcd, + 0x0a, 0x68, 0xf8, 0x87, 0x44, 0xf1, 0x92, 0xc1, 0xf4, 0xda, 0x8d, 0x06, + 0xd7, 0x7b, 0xe3, 0xee, 0x6f, 0x2f, 0x2d, 0x52, 0x6f, 0x13, 0x82, 0xef, + 0x2a, 0xa9, 0xbc, 0x7e, 0x6f, 0xde, 0xc1, 0xa1, 0xa1, 0x5b, 0xd7, 0x13, + 0x82, 0x12, 0x43, 0xb1, 0x9f, 0x7b, 0x3c, 0x5d, 0x46, 0xb2, 0x38, 0xed, + 0xb2, 0xd3, 0x85, 0xe1, 0xfc, 0x6f, 0xb5, 0xdf, 0x45, 0x4a, 0x5c, 0x6d, + 0x0c, 0x74, 0xc2, 0x94, 0x3a, 0xb0, 0x60, 0x90, 0xcf, 0x56, 0xf1, 0xf6, + 0x8a, 0x45, 0xbc, 0xff, 0xdc, 0xe1, 0x86, 0xf7, 0x63, 0xc4, 0x2c, 0xd0, + 0x48, 0x2f, 0xc1, 0xbb, 0x9c, 0x0a, 0x29, 0xd3, 0xe1, 0xac, 0x13, 0x82, + 0x3e, 0xb2, 0x25, 0xa4, 0x73, 0x06, 0xcd, 0xbf, 0x6d, 0x29, 0xa7, 0xd8, + 0x02, 0x47, 0xf1, 0x6b, 0x3f, 0x43, 0x9f, 0xc0, 0x89, 0x28, 0x25, 0x68, + 0x29, 0x21, 0x6c, 0x63, 0xe1, 0x96, 0x18, 0xaf, 0x9d, 0x19, 0xce, 0x3f, + 0xcb, 0x2f, 0x47, 0x44, 0x2e, 0xfb, 0xc9, 0xec, 0x4f, 0x47, 0x07, 0x3f, + 0x87, 0xf5, 0x22, 0x88, 0xa3, 0xcd, 0x01, 0x86, 0x05, 0xa0, 0x4c, 0xe5, + 0x12, 0xb9, 0x9e, 0x99, 0x19, 0x4c, 0x24, 0x1c, 0x3a, 0x05, 0xd6, 0x3d, + 0x55, 0x92, 0x24, 0x29, 0x87, 0x97, 0x07, 0x07, 0x68, 0x18, 0x18, 0x12, + 0x6a, 0x6a, 0xf8, 0xf8, 0xf8, 0x78, 0x90, 0x3f, 0x04, 0x14, 0xac, 0xd0, + 0x17, 0x05, 0xc6, 0xf1, 0x67, 0x16, 0x32, 0x02, 0x60, 0xca, 0xe7, 0x61, + 0xeb, 0x7e, 0xe3, 0x79, 0x34, 0xdc, 0x6f, 0x0d, 0x81, 0x3f, 0x5d, 0x46, + 0xa5, 0x53, 0x5b, 0x6d, 0xe7, 0x5d, 0x85, 0xf4, 0xbe, 0x78, 0x2b, 0x24, + 0x71, 0x99, 0x1f, 0x6e, 0x95, 0x99, 0x22, 0x8b, 0x64, 0x91, 0x4b, 0x18, + 0x3e, 0x53, 0xd3, 0x1b, 0x0f, 0x15, 0x9a, 0x04, 0x19, 0x4d, 0x22, 0x78, + 0xf6, 0xcd, 0xbb, 0x26, 0x92, 0x85, 0x29, 0x3b, 0x47, 0x19, 0x5e, 0xa9, + 0xe6, 0x24, 0xf6, 0x04, 0x74, 0x3e, 0x98, 0xac, 0x8a, 0x8c, 0x81, 0x59, + 0x85, 0xb6, 0x63, 0x75, 0x6e, 0x23, 0x44, 0xf2, 0xfa, 0x4b, 0xa3, 0x9a, + 0x68, 0xff, 0x73, 0x3b, 0x5d, 0x0e, 0x99, 0x2a, 0x90, 0x38, 0x16, 0x26, + 0x5b, 0x8d, 0xff, 0xf9, 0xd3, 0xbf, 0x69, 0xdd, 0x97, 0xe0, 0xf5, 0xe9, + 0xb6, 0xfc, 0x4f, 0xd9, 0x72, 0x46, 0xb3, 0xcf, 0x33, 0x87, 0xc8, 0xb7, + 0x6f, 0x1f, 0x00, 0x03, 0x28, 0x5d, 0x77, 0x77, 0x24, 0xf7, 0x4e, 0xd7, + 0x99, 0xa0, 0xae, 0xcd, 0xe1, 0xfc, 0xf2, 0x64, 0x6b, 0x11, 0x59, 0xe7, + 0xdb, 0x8d, 0xae, 0x37, 0xb3, 0x9f, 0x54, 0x56, 0x74, 0x6b, 0x98, 0x15, + 0x12, 0x7c, 0xf4, 0xd1, 0xdb, 0xb5, 0x06, 0x07, 0x54, 0xe0, 0x78, 0x63, + 0x45, 0xfb, 0x2f, 0x94, 0x80, 0x5c, 0x92, 0xfe, 0x5d, 0xb9, 0x49, 0x24, + 0xc8, 0x00, 0xf5, 0xfb, 0x8a, 0x0a, 0x3f, 0x37, 0x26, 0x99, 0x5a, 0x5e, + 0x85, 0x69, 0x15, 0xe3, 0x9e, 0xb1, 0x78, 0xf8, 0xd3, 0xe9, 0xbf, 0xb9, + 0xe7, 0x23, 0xa3, 0x4e, 0x57, 0x5b, 0xf4, 0x85, 0x26, 0x7b, 0xbf, 0x87, + 0x97, 0xeb, 0x2d, 0x82, 0xd6, 0x3a, 0xbc, 0x8e, 0xbf, 0x93, 0x9d, 0xf6, + 0x31, 0x21, 0xbb, 0x9e, 0xad, 0x44, 0x2c, 0xd5, 0x99, 0x7d, 0x23, 0xc7, + 0xb0, 0x68, 0x8f, 0x6d, 0x69, 0xe1, 0x0e, 0x0c, 0x0a, 0x72, 0xb8, 0x39, + 0x50, 0x94, 0xc9, 0xe0, 0x40, 0xc1, 0xc3, 0xc3, 0x03, 0x33, 0x1b, 0x41, + 0x03, 0xf3, 0xe5, 0x37, 0x07, 0x23, 0x37, 0x3d, 0xe6, 0xbb, 0x6e, 0x9c, + 0xc8, 0xb9, 0xed, 0xe9, 0x71, 0x59, 0x6b, 0xa4, 0x70, 0x5e, 0x96, 0x02, + 0xdd, 0xaf, 0x8d, 0x72, 0x62, 0xda, 0x79, 0x78, 0x77, 0xcc, 0xe2, 0x41, + 0xc8, 0x4a, 0xb1, 0x09, 0x41, 0x35, 0x17, 0xed, 0x02, 0xc0, 0x97, 0x9e, + 0x2e, 0x8c, 0xe4, 0x43, 0xf7, 0xd2, 0xfe, 0x87, 0x90, 0xa5, 0x50, 0x0d, + 0x1f, 0x22, 0xcc, 0x17, 0xf9, 0x47, 0x93, 0x0a, 0x67, 0x48, 0xcf, 0x20, + 0xd5, 0xc8, 0x0d, 0x68, 0xc1, 0x43, 0x63, 0x58, 0x83, 0xf7, 0xb8, 0xd1, + 0x4f, 0xf3, 0x0d, 0x3e, 0x41, 0x2c, 0x7b, 0x20, 0xfb, 0xbd, 0xab, 0x2c, + 0xc4, 0x3f, 0xdc, 0x4e, 0x7b, 0x6c, 0xcd, 0x5d, 0x12, 0xaa, 0x93, 0x6c, + 0x31, 0x80, 0x36, 0x1b, 0x01, 0x11, 0xba, 0x00, 0xbf, 0xfb, 0x92, 0x30, + 0x5c, 0x63, 0x39, 0x47, 0x73, 0x73, 0xa4, 0xaa, 0xf4, 0xe5, 0xb4, 0x6e, + 0x42, 0xe0, 0x9b, 0xa8, 0x28, 0xb4, 0x56, 0x83, 0xa5, 0xaa, 0xe1, 0xd9, + 0x79, 0xd8, 0xc4, 0xc2, 0xf2, 0x45, 0x67, 0xc4, 0xd4, 0x26, 0xc9, 0x83, + 0xeb, 0x23, 0xdd, 0x43, 0xbd, 0x6b, 0xe5, 0x25, 0xaf, 0x08, 0x04, 0xb1, + 0xb6, 0xda, 0x78, 0x50, 0x97, 0xba, 0x74, 0xe5, 0xc1, 0xc5, 0x85, 0x43, + 0x6f, 0xb9, 0xa0, 0x83, 0xfe, 0xc3, 0x83, 0xb5, 0x67, 0x7e, 0x92, 0x18, + 0x42, 0xb0, 0x3a, 0xc0, 0x68, 0xbf, 0x39, 0x83, 0x7b, 0x51, 0x3b, 0x44, + 0xf3, 0x0f, 0x08, 0x90, 0x13, 0x1a, 0xd0, 0x0d, 0x16, 0x01, 0xb3, 0x70, + 0x71, 0xbc, 0x10, 0x75, 0xd1, 0xb3, 0x43, 0x82, 0x8e, 0xaf, 0x70, 0x38, + 0x9f, 0x2e, 0x32, 0xc3, 0x46, 0xf4, 0x5b, 0x20, 0x57, 0x7a, 0xb1, 0xd6, + 0x18, 0xce, 0x74, 0x3c, 0xbd, 0x88, 0x38, 0xc4, 0xb9, 0x1b, 0x40, 0xdc, + 0x1a, 0x87, 0x6d, 0xf1, 0xca, 0x0a, 0x0a, 0x9c, 0xa8, 0x29, 0xc0, 0xdc, + 0xa8, 0x26, 0xe0, 0x94, 0xaa, 0x44, 0x32, 0x76, 0xbd, 0x60, 0x48, 0x27, + 0xd3, 0x95, 0x32, 0xdd, 0xdb, 0xde, 0xcc, 0xf0, 0xcc, 0xb9, 0x57, 0x23, + 0x47, 0xd2, 0xb4, 0xa8, 0xaf, 0x5f, 0x9f, 0x1a, 0x55, 0xbc, 0x98, 0xe3, + 0xd3, 0x8d, 0xad, 0xe9, 0xcc, 0x98, 0x4c, 0x5f, 0x08, 0x5c, 0x5c, 0xba, + 0x3b, 0x59, 0x2c, 0xa6, 0x0b, 0xcd, 0x20, 0x67, 0x53, 0x16, 0xb6, 0x4f, + 0x87, 0xe0, 0x3a, 0xdd, 0xdb, 0xfe, 0x76, 0xed, 0xaa, 0x45, 0x4f, 0xe7, + 0x8b, 0xd9, 0x06, 0x0b, 0x33, 0x99, 0xa7, 0xb3, 0x13, 0xd8, 0x26, 0x65, + 0xfb, 0xba, 0xe2, 0xf5, 0x61, 0xfd, 0x85, 0x30, 0x4f, 0x2e, 0x8d, 0x40, + 0x3f, 0x6f, 0xc7, 0x8e, 0x05, 0x5e, 0x6b, 0xc3, 0x81, 0xe0, 0xac, 0x72, + 0x62, 0x7b, 0x7f, 0x18, 0xcc, 0xfa, 0x2c, 0x3d, 0xb7, 0xb8, 0xb4, 0x84, + 0x87, 0x80, 0x80, 0x10, 0xb3, 0xe7, 0xcc, 0x90, 0x32, 0x3a, 0xd5, 0xea, + 0x62, 0x05, 0x78, 0xec, 0x03, 0x6b, 0x34, 0x60, 0xf4, 0xce, 0xce, 0xaa, + 0xdc, 0x9c, 0xfe, 0xc3, 0x6d, 0xb2, 0x2b, 0x1f, 0x22, 0xb5, 0x7e, 0x5b, + 0x87, 0x3b, 0x98, 0x9f, 0x92, 0x30, 0xf3, 0x32, 0xfb, 0xb1, 0x6f, 0x78, + 0x99, 0x9e, 0xe3, 0xb0, 0xbf, 0x59, 0x27, 0x95, 0x43, 0x70, 0xe9, 0xc1, + 0xd5, 0x66, 0x46, 0x1f, 0x1d, 0x92, 0x2e, 0xb1, 0x92, 0xb2, 0x0b, 0xb8, + 0xbe, 0xb1, 0xd7, 0x2d, 0x38, 0x10, 0x48, 0x2c, 0xad, 0xca, 0x30, 0xb5, + 0x77, 0x40, 0x4b, 0x33, 0xf5, 0x7f, 0xec, 0xe2, 0x1c, 0x2a, 0x84, 0xfe, + 0xdf, 0x96, 0xa3, 0xf6, 0x98, 0xac, 0x34, 0xef, 0x55, 0xb8, 0xe1, 0xd5, + 0x3e, 0x24, 0x5b, 0x79, 0x50, 0x35, 0xdc, 0x9d, 0xef, 0x3d, 0x02, 0x25, + 0x32, 0x8a, 0xd5, 0xe4, 0x20, 0x21, 0x88, 0x61, 0x4d, 0xe1, 0xbc, 0x9b, + 0xdd, 0xfb, 0xe1, 0x42, 0xdc, 0x78, 0x2c, 0xe0, 0xd7, 0x4c, 0x0b, 0x43, + 0x0c, 0xb7, 0xc2, 0x56, 0xe8, 0x7a, 0xbb, 0x87, 0x53, 0x51, 0xc9, 0xcd, + 0x98, 0xf5, 0xb8, 0x76, 0xf9, 0x3c, 0x34, 0xaf, 0x15, 0x92, 0xb5, 0x2e, + 0x3b, 0xee, 0x8c, 0xf8, 0x7d, 0x35, 0x9b, 0x41, 0xec, 0xc4, 0x76, 0x99, + 0xd2, 0xc9, 0x11, 0x62, 0x1f, 0xd3, 0xa2, 0x4f, 0x0d, 0x9b, 0x58, 0xdc, + 0x78, 0x63, 0x6b, 0x45, 0x52, 0x08, 0x42, 0x30, 0x0b, 0xb0, 0x1a, 0x93, + 0x08, 0x58, 0xbb, 0x07, 0x5f, 0xe3, 0xfb, 0x75, 0x7f, 0x8e, 0x2a, 0x77, + 0x42, 0xec, 0xb8, 0x42, 0x92, 0x09, 0x08, 0x78, 0x9a, 0xb1, 0x35, 0x56, + 0x66, 0x5b, 0xfd, 0x34, 0xd1, 0x66, 0xdf, 0x1c, 0x7c, 0x1d, 0xb2, 0xdc, + 0x7e, 0x7b, 0x7d, 0x3e, 0xfe, 0x8e, 0xb9, 0x5a, 0x63, 0xf3, 0xaf, 0xd1, + 0x73, 0x69, 0xbf, 0x24, 0xc7, 0xb7, 0xb7, 0x3b, 0x00, 0x6a, 0x73, 0x6f, + 0x4f, 0x8d, 0xf1, 0x39, 0x29, 0x64, 0x74, 0xd3, 0xe0, 0x6f, 0x62, 0xde, + 0x83, 0xe9, 0x52, 0x05, 0xa2, 0x26, 0x60, 0xe6, 0x07, 0xc0, 0xdc, 0xc7, + 0x48, 0xfd, 0x7c, 0xb2, 0x15, 0xd7, 0x02, 0x29, 0x76, 0x43, 0x1b, 0x6a, + 0x2a, 0xc3, 0x49, 0xdc, 0x62, 0x08, 0x09, 0x36, 0xd6, 0x83, 0x59, 0x15, + 0xd7, 0xf9, 0xd0, 0x22, 0xdc, 0x80, 0x9c, 0x99, 0x63, 0x13, 0x4d, 0x90, + 0xfd, 0xcc, 0x97, 0x41, 0x63, 0x96, 0x39, 0xfa, 0x16, 0x3a, 0x8c, 0x00, + 0x0b, 0xf2, 0xab, 0x4e, 0x7e, 0x38, 0x0e, 0x33, 0x01, 0x0b, 0x92, 0xd7, + 0x4f, 0xed, 0x98, 0xd0, 0x62, 0x49, 0xf1, 0xd1, 0xcc, 0xf8, 0x8c, 0x2e, + 0x2e, 0x82, 0xf9, 0xbd, 0xee, 0x66, 0x73, 0x44, 0xb4, 0x28, 0xbf, 0x7e, + 0x45, 0x68, 0xb2, 0x5d, 0x2d, 0x4b, 0xe9, 0xf8, 0x95, 0x90, 0xa0, 0xa8, + 0xa1, 0x11, 0xee, 0xb0, 0x3d, 0x58, 0x3a, 0x8c, 0x14, 0x19, 0x79, 0x6c, + 0xe2, 0x97, 0xbb, 0x63, 0xeb, 0xb3, 0x2b, 0xa1, 0xdc, 0x63, 0x5a, 0xee, + 0x47, 0x5e, 0x5c, 0x68, 0xb6, 0xb9, 0x5a, 0xb4, 0xbe, 0x79, 0x65, 0x33, + 0xde, 0xda, 0xd3, 0xb1, 0x77, 0x71, 0x48, 0x5b, 0x26, 0xc8, 0x1a, 0x4d, + 0xca, 0x42, 0x7f, 0x4a, 0xab, 0x74, 0x95, 0x94, 0xeb, 0xf2, 0xf1, 0x70, + 0x04, 0x75, 0x7b, 0x2e, 0x5b, 0xa7, 0x1f, 0x7f, 0xf6, 0x71, 0xf1, 0x8a, + 0xed, 0x99, 0x72, 0x77, 0xec, 0x17, 0xad, 0x65, 0x88, 0x57, 0x89, 0x05, + 0xab, 0x35, 0x41, 0x43, 0xa6, 0x1c, 0x76, 0x7a, 0xf9, 0x10, 0x24, 0x49, + 0xa3, 0x8a, 0x74, 0x34, 0x95, 0x42, 0x38, 0x60, 0xf0, 0xef, 0x79, 0x8c, + 0xfa, 0x3c, 0xa7, 0xbd, 0x31, 0x3c, 0x00, 0xb9, 0x2b, 0xab, 0x86, 0x4d, + 0xeb, 0xa6, 0x8a, 0x65, 0x33, 0xa4, 0x56, 0x17, 0x35, 0x35, 0x35, 0xe1, + 0xd1, 0xd0, 0xd4, 0x17, 0x36, 0xaf, 0x74, 0x2b, 0x25, 0x5a, 0xd5, 0x25, + 0x00, 0xb0, 0x5c, 0xac, 0xdf, 0xf2, 0x49, 0xcd, 0xc0, 0x2f, 0x07, 0xc2, + 0x12, 0x4d, 0x7d, 0xef, 0xa2, 0xe7, 0xba, 0x5c, 0x97, 0x8d, 0xb9, 0x31, + 0x04, 0x6f, 0x78, 0x28, 0x69, 0xe1, 0x21, 0x3c, 0x2e, 0x52, 0x1c, 0xc0, + 0x5e, 0x25, 0x88, 0xfd, 0xc6, 0xf4, 0xf5, 0xe5, 0xed, 0xd9, 0x77, 0x43, + 0x2e, 0xfc, 0x7d, 0xe2, 0x83, 0x28, 0xd6, 0xeb, 0xe6, 0x3f, 0x0d, 0x0f, + 0x5a, 0xf6, 0x68, 0xa2, 0x89, 0x30, 0xc8, 0x61, 0xc1, 0xd2, 0x91, 0xdb, + 0xe6, 0x4a, 0x4a, 0xa1, 0x60, 0x27, 0x93, 0x38, 0xed, 0xeb, 0x90, 0x88, + 0x23, 0xf2, 0x9c, 0x15, 0x7f, 0x36, 0x3f, 0x3e, 0x03, 0x83, 0x06, 0x63, + 0x3f, 0x47, 0xd1, 0xaa, 0x57, 0x7d, 0x01, 0xf2, 0x10, 0x47, 0xc4, 0xdf, + 0x7b, 0x77, 0xfa, 0x8f, 0x76, 0xcc, 0xe3, 0x62, 0x03, 0x42, 0x47, 0x57, + 0x77, 0xce, 0xa4, 0xf6, 0x52, 0x72, 0x74, 0x6c, 0x2e, 0x9d, 0x88, 0x3d, + 0xcf, 0x4a, 0x22, 0x07, 0xe3, 0xde, 0xab, 0x85, 0x94, 0x45, 0x29, 0x8d, + 0x30, 0xa7, 0xe2, 0x15, 0x46, 0xf0, 0xdd, 0xa3, 0x7d, 0x5e, 0x9c, 0x9f, + 0xb7, 0x1a, 0xc4, 0xa8, 0x34, 0xad, 0x6a, 0xcc, 0xb0, 0xb0, 0x55, 0xa5, + 0x96, 0x48, 0x81, 0x3e, 0x22, 0x8c, 0xcc, 0x93, 0x87, 0xda, 0x8c, 0x2f, + 0xe8, 0xdd, 0x6c, 0xd0, 0xa4, 0xe2, 0xb9, 0x0f, 0xdb, 0x87, 0x15, 0xeb, + 0xb9, 0xaa, 0x60, 0xb2, 0x75, 0x21, 0xf0, 0x81, 0x10, 0x0f, 0x60, 0x8d, + 0x2e, 0x47, 0x9b, 0x2b, 0x16, 0x7e, 0x6d, 0x1b, 0x9d, 0xce, 0x47, 0xc9, + 0x6f, 0xfb, 0xbb, 0xa3, 0x29, 0x5a, 0x9a, 0x43, 0x13, 0x13, 0x68, 0x5e, + 0xf7, 0x67, 0x62, 0x29, 0x0c, 0xba, 0x1b, 0x1b, 0x1b, 0x20, 0x50, 0x2a, + 0x8b, 0x09, 0xa2, 0xb7, 0x8f, 0xcf, 0xdc, 0x5e, 0xed, 0x92, 0x35, 0x9b, + 0xd5, 0x3c, 0xb2, 0x9e, 0x9e, 0x1e, 0x0d, 0x5e, 0x1f, 0x53, 0x33, 0x81, + 0xae, 0x07, 0x74, 0x2b, 0xc3, 0xe1, 0xc6, 0x71, 0x6c, 0x4c, 0x4e, 0x87, + 0x7e, 0x5e, 0x36, 0x1f, 0x50, 0x77, 0x2f, 0xff, 0x0c, 0xf9, 0x94, 0xb0, + 0xc3, 0x4a, 0xf1, 0xd4, 0xed, 0x24, 0xbe, 0x51, 0xfa, 0x9d, 0x9e, 0x32, + 0x49, 0x6d, 0x5d, 0xf3, 0xfb, 0x4e, 0xff, 0x2a, 0x83, 0x0e, 0xc4, 0xef, + 0xcf, 0xc5, 0xb4, 0x8c, 0x51, 0x58, 0x6c, 0xc0, 0x0b, 0xdb, 0xae, 0x0f, + 0xcf, 0x67, 0x31, 0xb2, 0xe0, 0xf1, 0x7a, 0xb1, 0xfa, 0x86, 0x0a, 0x52, + 0x96, 0x40, 0xeb, 0x7e, 0x39, 0xec, 0x6b, 0xf0, 0xec, 0x65, 0x15, 0x1d, + 0x29, 0xe1, 0xe1, 0xe6, 0xe1, 0x39, 0x02, 0xaa, 0x70, 0x12, 0x28, 0xf4, + 0xca, 0x0a, 0x63, 0x5b, 0x5b, 0x3d, 0x92, 0x2b, 0x7d, 0x9a, 0x24, 0x52, + 0x01, 0x01, 0x3d, 0xd9, 0xbd, 0xfd, 0x7d, 0x38, 0x80, 0xdd, 0x6f, 0x8f, + 0x17, 0xca, 0x87, 0xeb, 0xe6, 0x9e, 0xc3, 0x16, 0x08, 0x84, 0xdf, 0xb2, + 0x1f, 0x0e, 0xcb, 0x3d, 0x98, 0x58, 0x3f, 0xa9, 0xb9, 0xdf, 0xdd, 0x51, + 0xad, 0xcf, 0x1e, 0x45, 0x89, 0x2f, 0x6d, 0x7c, 0x47, 0x2d, 0x59, 0x7a, + 0xca, 0xcf, 0x97, 0xf6, 0xd0, 0x52, 0xfc, 0x25, 0x44, 0x2d, 0xb1, 0xfd, + 0x36, 0x4b, 0x61, 0x8e, 0x4d, 0x56, 0x70, 0x67, 0x4a, 0xa7, 0x16, 0x15, + 0xd7, 0xbf, 0xc5, 0x2b, 0x8f, 0x1d, 0x59, 0xc8, 0x8e, 0x4c, 0xa6, 0x54, + 0x67, 0x74, 0x1e, 0x4b, 0x1c, 0xcc, 0x9d, 0x00, 0xc7, 0x59, 0x36, 0x5b, + 0x39, 0x62, 0x00, 0x86, 0x0d, 0x93, 0x4b, 0x31, 0xfd, 0x5c, 0xab, 0x41, + 0x57, 0x6f, 0x55, 0x92, 0x35, 0x9d, 0x1b, 0x13, 0x33, 0xb2, 0x32, 0x43, + 0x1a, 0x0f, 0x3f, 0x30, 0x50, 0x04, 0x61, 0x57, 0xa9, 0xd5, 0x10, 0xd8, + 0xd6, 0xc6, 0x0b, 0xca, 0x75, 0xda, 0xff, 0x6b, 0xe9, 0x34, 0xea, 0x25, + 0x72, 0x84, 0x49, 0x8c, 0x86, 0xeb, 0x5d, 0xf7, 0xd2, 0x81, 0x78, 0x76, + 0x9f, 0x6f, 0xc4, 0xec, 0xbb, 0xe4, 0xf6, 0x47, 0xbc, 0xca, 0x2d, 0xbd, + 0x78, 0x14, 0xec, 0xec, 0x9b, 0x2d, 0x42, 0x52, 0x9d, 0x33, 0x0b, 0x21, + 0x92, 0x10, 0x0c, 0x76, 0x16, 0x89, 0xd9, 0xb8, 0xf6, 0x79, 0xfe, 0xef, + 0x47, 0x5c, 0xce, 0x94, 0xf3, 0x88, 0x56, 0x68, 0xfc, 0xef, 0xa4, 0x45, + 0xa3, 0x3a, 0xcd, 0x54, 0xae, 0x76, 0xce, 0x35, 0x22, 0xce, 0x9a, 0x29, + 0x02, 0x27, 0x10, 0xba, 0x74, 0x21, 0x35, 0x0d, 0x26, 0xba, 0x99, 0x85, + 0x45, 0x69, 0x4a, 0x62, 0x79, 0xa8, 0x90, 0xb5, 0x35, 0xdd, 0xd9, 0x6a, + 0x5b, 0x58, 0x89, 0x7c, 0xce, 0xd6, 0xd1, 0x5c, 0x39, 0x97, 0xcb, 0x11, + 0xd6, 0x7c, 0x85, 0x66, 0x01, 0xc7, 0xd0, 0x4c, 0x5d, 0xfd, 0x02, 0x7f, + 0xca, 0x28, 0x4c, 0xca, 0xa8, 0x2a, 0x7f, 0x94, 0xb4, 0x4c, 0xa5, 0xba, + 0xcf, 0xe8, 0xcc, 0xd4, 0xc2, 0xe7, 0x72, 0x1c, 0xb9, 0x72, 0x74, 0x38, + 0xc7, 0xc3, 0x3d, 0x28, 0xef, 0xb7, 0x55, 0x06, 0x2c, 0x1c, 0x75, 0x7d, + 0xd4, 0xfb, 0x83, 0x96, 0x63, 0xc9, 0x09, 0x9a, 0x08, 0x28, 0x83, 0xba, + 0x90, 0x78, 0xa1, 0x48, 0x0d, 0xb3, 0x11, 0x8c, 0x74, 0x3e, 0x94, 0xb6, + 0x3f, 0x70, 0x79, 0x44, 0xf6, 0x9b, 0xb5, 0x4b, 0xf9, 0x13, 0x45, 0xd3, + 0xa9, 0x8f, 0x20, 0xdd, 0xbc, 0xd5, 0x44, 0x85, 0xee, 0xa1, 0x32, 0xb1, + 0x99, 0xa9, 0xba, 0x84, 0x1c, 0x81, 0xc4, 0x19, 0x24, 0x8c, 0x34, 0x42, + 0x44, 0x0f, 0x0b, 0x68, 0x77, 0xe3, 0x17, 0x0c, 0x63, 0x20, 0x9a, 0x24, + 0x97, 0x3f, 0x7f, 0xfe, 0x4c, 0x76, 0xfa, 0xdc, 0xca, 0xaa, 0x21, 0x22, + 0x4a, 0xad, 0x1e, 0x15, 0x17, 0x17, 0x33, 0x71, 0x70, 0x88, 0xeb, 0xe9, + 0x45, 0xa8, 0x3f, 0xf5, 0x6c, 0xbb, 0x4b, 0x9a, 0x38, 0x5e, 0x78, 0xac, + 0x94, 0xe9, 0x2d, 0x70, 0xe7, 0xe9, 0xfe, 0xdb, 0xcc, 0xa1, 0xa7, 0xad, + 0xb9, 0x3e, 0x57, 0xe6, 0xb2, 0x27, 0xc5, 0xb8, 0x29, 0x4f, 0x78, 0xec, + 0x51, 0x56, 0x47, 0xbf, 0xbe, 0x81, 0x69, 0xac, 0x4a, 0x47, 0x92, 0xbe, + 0x1e, 0x19, 0xfd, 0xaf, 0x53, 0x72, 0x58, 0xe1, 0x35, 0xad, 0x98, 0x7b, + 0xc7, 0x59, 0x6e, 0xf2, 0xeb, 0x4e, 0xb0, 0xdc, 0x6f, 0x0c, 0xa2, 0x89, + 0x36, 0x46, 0x31, 0x13, 0x01, 0x15, 0x1a, 0x56, 0x5c, 0x75, 0xd3, 0xb1, + 0x36, 0xe7, 0x8b, 0xc1, 0x80, 0x4a, 0xda, 0xf4, 0x44, 0x80, 0x2b, 0x56, + 0xda, 0x45, 0x12, 0x5d, 0x1a, 0xd5, 0xe6, 0x75, 0x0a, 0xf3, 0x58, 0x0d, + 0xba, 0x41, 0x0f, 0xcf, 0xcf, 0x0b, 0xa3, 0x7a, 0xc6, 0x83, 0xd1, 0x8a, + 0x04, 0x4e, 0x5c, 0x45, 0xfb, 0xc8, 0x11, 0x2a, 0xb0, 0x11, 0x2a, 0xef, + 0x5f, 0xff, 0xc9, 0x8d, 0xdb, 0xd4, 0x9e, 0x04, 0x5d, 0x3e, 0xac, 0xf7, + 0x96, 0x5a, 0xaa, 0xee, 0x66, 0xf7, 0x53, 0x19, 0xdf, 0xc6, 0xf9, 0xa9, + 0x3c, 0xae, 0xf5, 0x51, 0x21, 0x54, 0xbf, 0xf5, 0x0f, 0x6f, 0x3b, 0x66, + 0xc4, 0x1b, 0xb1, 0x40, 0x67, 0x89, 0xc8, 0x1d, 0x04, 0x23, 0x72, 0x71, + 0x8f, 0xb3, 0xcb, 0xca, 0xbe, 0x1e, 0xe3, 0xa6, 0x9d, 0x5c, 0xda, 0x0b, + 0x69, 0x6e, 0x4a, 0xe7, 0x84, 0xa4, 0x31, 0x9b, 0x46, 0xe3, 0x85, 0x33, + 0x7f, 0xe2, 0x27, 0x30, 0x91, 0x02, 0x80, 0xe0, 0xfd, 0xa0, 0x65, 0x79, + 0x71, 0x49, 0x93, 0x77, 0x9c, 0x17, 0x19, 0x81, 0x21, 0x25, 0xea, 0x6f, + 0x16, 0xef, 0x87, 0x20, 0xf2, 0xac, 0x8f, 0x0e, 0x0f, 0x97, 0xf6, 0x72, + 0xd1, 0xd2, 0x1e, 0xcf, 0x85, 0x07, 0xe8, 0x54, 0xad, 0x7a, 0x3f, 0xb4, + 0xa2, 0xaf, 0xd1, 0xc2, 0xab, 0xed, 0x51, 0xba, 0x63, 0xe4, 0x04, 0xbe, + 0x0e, 0x31, 0x92, 0x1e, 0x9a, 0x50, 0xca, 0xe9, 0xb6, 0x87, 0x08, 0x09, + 0xca, 0x47, 0x13, 0x4e, 0xea, 0x8e, 0x6b, 0x7f, 0x9b, 0x61, 0xcb, 0xe6, + 0xf3, 0x5b, 0xe5, 0xcc, 0xbe, 0x16, 0xa5, 0xf4, 0xfa, 0x32, 0x17, 0x37, + 0x1f, 0x5c, 0x0c, 0x09, 0x48, 0xfe, 0xc8, 0x66, 0xef, 0x77, 0xd9, 0xd7, + 0xeb, 0x1a, 0x91, 0x78, 0x96, 0x3f, 0x2c, 0xc6, 0x6b, 0x45, 0x41, 0x9c, + 0x77, 0x36, 0x7a, 0xa1, 0x08, 0x7d, 0xbd, 0xe9, 0x85, 0xcc, 0x70, 0x52, + 0x52, 0x81, 0xc9, 0x62, 0xa5, 0x2a, 0x1f, 0x85, 0xcf, 0x62, 0xbd, 0xc8, + 0x94, 0x85, 0x3b, 0x6a, 0x58, 0xab, 0x31, 0xd7, 0xba, 0x83, 0x07, 0x8b, + 0x4e, 0xd0, 0x8d, 0xd0, 0x41, 0xa7, 0xcb, 0xe3, 0x6e, 0x7c, 0x15, 0x2e, + 0xb0, 0xf8, 0x36, 0x07, 0x59, 0xef, 0xc8, 0x30, 0x0c, 0xab, 0xd1, 0xe0, + 0xc1, 0xd8, 0x78, 0xc6, 0x0f, 0x9b, 0x5e, 0xac, 0x7a, 0x8d, 0xf1, 0x6b, + 0x26, 0x3e, 0x43, 0x1f, 0x1e, 0x64, 0x50, 0x1b, 0x4c, 0x7e, 0x9f, 0x99, + 0xeb, 0x04, 0x88, 0x1f, 0x08, 0x94, 0xce, 0xb9, 0xde, 0xb3, 0xe9, 0xa8, + 0xdd, 0x01, 0x55, 0xa8, 0xaf, 0x40, 0xad, 0xe4, 0xa5, 0xc6, 0x61, 0x36, + 0x96, 0x8b, 0xfe, 0x72, 0xd1, 0x85, 0x66, 0x60, 0x66, 0xa3, 0x38, 0xb1, + 0x8c, 0x87, 0x53, 0x9a, 0xc6, 0x6d, 0xb9, 0x0d, 0x48, 0xcf, 0x21, 0xf0, + 0xc8, 0xe9, 0x6a, 0x7d, 0x41, 0xeb, 0xa5, 0x3f, 0x62, 0x25, 0x5e, 0x32, + 0xd9, 0x7c, 0x2d, 0x81, 0x61, 0x05, 0x27, 0x5f, 0x53, 0xf2, 0x7f, 0x4b, + 0x29, 0x0f, 0x21, 0x43, 0xf0, 0x12, 0x20, 0x79, 0x37, 0xb8, 0xf3, 0x68, + 0xd0, 0xe1, 0x80, 0x43, 0x7b, 0x92, 0xf9, 0x25, 0x98, 0x1d, 0xde, 0xb4, + 0x56, 0xa2, 0x22, 0xbe, 0x79, 0x2b, 0xe1, 0xe3, 0x54, 0xbf, 0xee, 0xce, + 0xcd, 0x21, 0x0f, 0xd4, 0x2c, 0xc5, 0xee, 0xbc, 0x7d, 0x3c, 0x77, 0x34, + 0x0b, 0xd4, 0x9d, 0x94, 0x95, 0xdd, 0xe9, 0x5c, 0xa2, 0xf4, 0xe8, 0xe8, + 0x6d, 0x22, 0xff, 0x35, 0xb2, 0x77, 0x31, 0x3c, 0x5b, 0x83, 0xc9, 0xf8, + 0x47, 0x01, 0x32, 0xa8, 0x9c, 0x5e, 0x6d, 0xaf, 0xd8, 0x72, 0x3b, 0x3a, + 0x3a, 0x9a, 0xc6, 0x94, 0xc3, 0x9b, 0x94, 0x94, 0xd4, 0xc0, 0xc8, 0x28, + 0x30, 0x3f, 0x9f, 0xb4, 0xb2, 0x7a, 0xb5, 0x54, 0xb9, 0x04, 0xd1, 0x63, + 0x1f, 0xb4, 0xb1, 0xb5, 0x15, 0xc8, 0xeb, 0x76, 0x06, 0xa2, 0x7e, 0x5c, + 0x62, 0xdd, 0xc9, 0xe1, 0x76, 0x4b, 0xd9, 0x03, 0x4f, 0xb2, 0xa2, 0x0f, + 0xfd, 0xd5, 0x85, 0x03, 0x89, 0x0a, 0x7e, 0xef, 0x4e, 0x0c, 0x39, 0x1e, + 0x19, 0xdf, 0xea, 0x60, 0x62, 0xbd, 0x6e, 0xcd, 0xc8, 0xfa, 0xac, 0xea, + 0x00, 0x01, 0x29, 0x1c, 0xf5, 0x13, 0xd3, 0x33, 0x61, 0x30, 0x62, 0x60, + 0x9b, 0xdb, 0x0f, 0xa1, 0x90, 0x42, 0xdd, 0x64, 0x4c, 0xf7, 0xf3, 0x69, + 0xad, 0xcb, 0x9c, 0x8e, 0xf7, 0xcb, 0x19, 0xd8, 0x3e, 0xfd, 0x77, 0x54, + 0x07, 0x5f, 0x47, 0x9b, 0x1b, 0xa8, 0x3c, 0x3a, 0x3e, 0x7e, 0x74, 0x57, + 0xab, 0xda, 0xcb, 0x96, 0x5a, 0x43, 0x5b, 0x7b, 0xfb, 0xb8, 0xba, 0x6b, + 0xfe, 0xa9, 0x95, 0xd5, 0x74, 0xac, 0x3b, 0x04, 0x09, 0xd7, 0xc0, 0xc4, + 0x44, 0x75, 0x53, 0x53, 0x13, 0xca, 0x96, 0x94, 0x8d, 0x65, 0x11, 0x93, + 0x47, 0x21, 0xff, 0xf8, 0x8a, 0x1b, 0x73, 0xb2, 0xc4, 0x6b, 0xa8, 0xcc, + 0x94, 0x49, 0xa7, 0x6a, 0xbb, 0xf7, 0xe4, 0x44, 0xf0, 0x90, 0x86, 0x12, + 0x1d, 0x5e, 0x2b, 0x28, 0x73, 0x32, 0x83, 0x09, 0x4b, 0xb5, 0x46, 0x8e, + 0x72, 0x34, 0x47, 0x7f, 0x89, 0x95, 0x80, 0xd6, 0x29, 0x1a, 0x15, 0xad, + 0xa7, 0x70, 0xb3, 0x83, 0xb6, 0x3e, 0xc9, 0xfa, 0xa8, 0xb9, 0x8d, 0xcd, + 0xd4, 0xc5, 0x28, 0xfa, 0xff, 0xee, 0x02, 0x84, 0x09, 0x75, 0xab, 0xb3, + 0x9b, 0x7d, 0xa5, 0xa6, 0x16, 0xd2, 0xd1, 0x21, 0xe4, 0xe3, 0xe7, 0xbf, + 0xad, 0x48, 0xb3, 0x4d, 0x65, 0x36, 0x86, 0xe5, 0x22, 0x44, 0xdd, 0x1b, + 0xcf, 0x08, 0x7b, 0x79, 0x69, 0xbd, 0xa5, 0x6e, 0xaa, 0xad, 0xed, 0xc9, + 0xe6, 0xf7, 0x9a, 0x6c, 0xb2, 0xd3, 0xa7, 0xb7, 0x28, 0xf1, 0x7b, 0xe0, + 0x63, 0x98, 0xa7, 0xcb, 0x46, 0xdd, 0xd7, 0x6d, 0x5c, 0x7c, 0xdb, 0x47, + 0x68, 0x30, 0xc3, 0xa2, 0x88, 0xfe, 0x35, 0xba, 0x7d, 0x77, 0xfc, 0x9d, + 0x5d, 0x04, 0xf3, 0xe3, 0xd9, 0xd4, 0x90, 0x01, 0xef, 0x3f, 0x42, 0xbf, + 0xbe, 0xd4, 0xfc, 0x31, 0x0b, 0x7a, 0x76, 0x1e, 0xe8, 0xc9, 0x11, 0x18, + 0xfa, 0xb7, 0x0d, 0x3b, 0xbf, 0x94, 0x0a, 0xe0, 0x76, 0x20, 0xe9, 0xa7, + 0x48, 0xd1, 0xa3, 0x5b, 0x36, 0x51, 0x23, 0x04, 0x22, 0x41, 0x79, 0x96, + 0xf0, 0x44, 0x72, 0x59, 0xa6, 0x4f, 0x88, 0xb3, 0x83, 0x5f, 0xbf, 0x7e, + 0xf5, 0x9c, 0x16, 0xbd, 0x07, 0xf8, 0x16, 0xc8, 0xf0, 0xd6, 0xe3, 0xf5, + 0xbe, 0x46, 0x9d, 0x29, 0x8a, 0xb5, 0x0d, 0xfb, 0xb1, 0xd9, 0xf9, 0xce, + 0x4e, 0x70, 0x14, 0x2e, 0x63, 0xe7, 0x54, 0x6a, 0xca, 0x6b, 0x53, 0x22, + 0x6d, 0xe2, 0xcf, 0xe1, 0x5d, 0xfc, 0x53, 0xf5, 0x9c, 0x1a, 0x0d, 0xba, + 0xb1, 0x6c, 0x36, 0x68, 0x81, 0x4a, 0xdd, 0xb9, 0x1d, 0x64, 0xb2, 0xbb, + 0x6d, 0x47, 0x1f, 0xbe, 0x9b, 0x02, 0xec, 0xbc, 0x52, 0x61, 0xb9, 0x03, + 0x59, 0xf4, 0x48, 0x47, 0x47, 0xcc, 0x28, 0x63, 0x5f, 0x68, 0x73, 0x76, + 0xe2, 0xd6, 0x90, 0x34, 0x04, 0x81, 0x1c, 0x4e, 0x04, 0x12, 0xfc, 0x9d, + 0xa4, 0x7d, 0x5c, 0x9c, 0x6d, 0x5b, 0x67, 0x42, 0x22, 0xbe, 0x58, 0x09, + 0x23, 0x29, 0xcf, 0xef, 0x9c, 0x2c, 0xe9, 0xe2, 0xa6, 0xb6, 0x10, 0x7f, + 0x9c, 0xae, 0x7a, 0x8c, 0x6a, 0x0d, 0x5e, 0x46, 0x7c, 0x8e, 0x36, 0xf7, + 0xc2, 0xff, 0xa1, 0x65, 0x7f, 0xe9, 0xaa, 0x01, 0x03, 0xd0, 0xb1, 0x42, + 0x78, 0x3a, 0x35, 0xd2, 0x00, 0x93, 0x49, 0x68, 0xbd, 0x79, 0xb6, 0x4c, + 0x08, 0x61, 0xa3, 0x4d, 0x50, 0x9f, 0x81, 0x0d, 0x0a, 0x0c, 0x5a, 0x36, + 0x7a, 0xef, 0xc2, 0x55, 0xdd, 0xfe, 0xef, 0x3f, 0x49, 0xc0, 0xba, 0x1c, + 0x29, 0x92, 0xad, 0x1a, 0x9b, 0x98, 0x84, 0x88, 0x45, 0xe1, 0x6c, 0x66, + 0xb9, 0xad, 0xf5, 0x00, 0x39, 0x73, 0xd8, 0xe8, 0x86, 0xe8, 0xef, 0xef, + 0x17, 0xa2, 0xc3, 0x51, 0xd7, 0x86, 0x6d, 0x70, 0x39, 0x9e, 0x07, 0xf3, + 0xba, 0xd2, 0x99, 0x4e, 0x64, 0xeb, 0x16, 0x30, 0x42, 0x15, 0x7d, 0xb5, + 0xa2, 0x60, 0x9f, 0x23, 0x90, 0xd2, 0x07, 0x45, 0xe6, 0x33, 0x79, 0x5d, + 0xa1, 0x7b, 0xd7, 0xbc, 0x78, 0x51, 0xab, 0xa4, 0xa1, 0xb1, 0x0d, 0x30, + 0x69, 0xe6, 0x34, 0x58, 0xd4, 0x39, 0x28, 0x59, 0x9f, 0x10, 0x6e, 0xb9, + 0x52, 0x1d, 0x60, 0xf5, 0xc5, 0x70, 0x90, 0x98, 0x7f, 0x66, 0xac, 0x3e, + 0xd7, 0x94, 0xcf, 0xae, 0x88, 0xca, 0x3d, 0xbc, 0x41, 0x41, 0x26, 0x53, + 0x2c, 0x0f, 0xc5, 0x38, 0x38, 0x8f, 0xd8, 0x75, 0xa2, 0xec, 0x1e, 0xce, + 0x33, 0x2d, 0x61, 0x4c, 0xd3, 0x09, 0xb8, 0x19, 0xd3, 0x21, 0x2f, 0x32, + 0xdd, 0xba, 0x48, 0xa3, 0xe5, 0xf2, 0xda, 0xcd, 0x9e, 0xbf, 0x0a, 0xf1, + 0xe0, 0x63, 0xf0, 0xd6, 0x6e, 0x23, 0xe5, 0x9a, 0xc4, 0x85, 0xf2, 0x84, + 0xcd, 0x4b, 0xab, 0x74, 0x2d, 0x4b, 0xb6, 0x48, 0xe0, 0x9d, 0x9a, 0x60, + 0x3a, 0x2d, 0x98, 0xf6, 0xaf, 0xba, 0xb8, 0xb0, 0x27, 0xe4, 0xf7, 0x54, + 0x89, 0xc3, 0x3f, 0x84, 0x0b, 0x35, 0xbc, 0x78, 0x79, 0x74, 0xd2, 0x69, + 0x71, 0x84, 0x71, 0x3b, 0x5b, 0x11, 0x36, 0x32, 0xca, 0x3f, 0x3a, 0x22, + 0xa1, 0xa2, 0x82, 0xf3, 0x79, 0xbe, 0x1b, 0xf8, 0x49, 0xf2, 0x6d, 0x36, + 0x72, 0x40, 0x45, 0x42, 0x4f, 0x8f, 0xa8, 0xa2, 0xb2, 0x52, 0xf5, 0x50, + 0xbf, 0xad, 0x53, 0x33, 0xba, 0x31, 0xbb, 0xaa, 0x55, 0x49, 0x9f, 0x6a, + 0xa5, 0xf9, 0x1d, 0x5c, 0xee, 0xf7, 0xf0, 0xf9, 0xd2, 0xc4, 0x33, 0xd7, + 0xa9, 0x85, 0xde, 0x95, 0x06, 0x2b, 0x79, 0x06, 0x6f, 0x8f, 0x84, 0xf9, + 0x08, 0x3a, 0x4b, 0x18, 0xd9, 0x13, 0x53, 0xf8, 0xcb, 0xc1, 0x39, 0x5d, + 0xbc, 0xce, 0xea, 0x20, 0xd3, 0xa3, 0xe5, 0x9b, 0x1c, 0x43, 0x58, 0x4c, + 0xcb, 0x8c, 0xc4, 0x46, 0x65, 0x4f, 0x87, 0x25, 0x96, 0xec, 0x0b, 0x0b, + 0x19, 0x9c, 0xf6, 0x3d, 0xe1, 0x40, 0xda, 0xa8, 0x9b, 0x8a, 0xdb, 0x7f, + 0xad, 0xc1, 0xa3, 0x9b, 0xb9, 0x4e, 0xcf, 0x1c, 0x07, 0xb8, 0x18, 0xe1, + 0x6f, 0x24, 0x10, 0x1b, 0x35, 0x28, 0x64, 0x4c, 0xf2, 0xa5, 0x85, 0x53, + 0x6e, 0xd3, 0x46, 0x3f, 0xf6, 0x93, 0x13, 0xe9, 0x1b, 0x9a, 0x9a, 0x24, + 0xb4, 0xb4, 0x96, 0x09, 0xd6, 0x48, 0xdb, 0x23, 0x32, 0x38, 0xed, 0x48, + 0xa9, 0xa9, 0x25, 0xd9, 0xcf, 0x16, 0xc8, 0x40, 0x56, 0x38, 0x13, 0x93, + 0x05, 0xe2, 0xe9, 0xf1, 0xfa, 0x0a, 0xd1, 0xf1, 0xe7, 0x3e, 0x01, 0x63, + 0x99, 0xd3, 0xa9, 0x50, 0x38, 0xa3, 0x9b, 0x68, 0x7e, 0xef, 0xfc, 0xdb, + 0xe7, 0x6b, 0x28, 0x14, 0xe2, 0x59, 0xb9, 0x98, 0xc8, 0xdb, 0x33, 0xf1, + 0xb9, 0xca, 0xc1, 0xbd, 0xae, 0xac, 0xe4, 0xbf, 0x08, 0xde, 0x59, 0xa2, + 0x25, 0xe9, 0x2d, 0xcb, 0x8b, 0xea, 0xa0, 0x3a, 0x35, 0x39, 0x90, 0x7c, + 0x5a, 0xdd, 0xdc, 0x0b, 0x98, 0xd5, 0xa9, 0x93, 0xb8, 0x9c, 0x9f, 0x68, + 0x04, 0xde, 0x2c, 0x09, 0xce, 0x06, 0xfa, 0xe7, 0xb4, 0x6f, 0x19, 0xd2, + 0x8b, 0x2f, 0xb7, 0x4c, 0x60, 0xff, 0xea, 0xb6, 0x84, 0x29, 0xa7, 0xd8, + 0x06, 0x8d, 0x9b, 0x16, 0x24, 0xd5, 0x05, 0xad, 0x91, 0x9d, 0x69, 0xd2, + 0x21, 0xd6, 0x3a, 0x30, 0x5e, 0xd0, 0xe5, 0x15, 0xda, 0xb9, 0x3b, 0x38, + 0x30, 0x0f, 0xc6, 0x11, 0xa3, 0x59, 0x59, 0x59, 0x75, 0x1c, 0xcd, 0x4d, + 0x2e, 0x75, 0x78, 0x71, 0xfe, 0xcd, 0xe4, 0x2e, 0xc0, 0xbf, 0x3f, 0xfe, + 0xe4, 0x1f, 0x6b, 0x43, 0xb0, 0x86, 0x5d, 0xff, 0x29, 0x07, 0x8e, 0x62, + 0x7c, 0xe3, 0x69, 0x75, 0x1a, 0x1f, 0x06, 0x59, 0x79, 0x27, 0x23, 0xc1, + 0x49, 0x31, 0x5f, 0x65, 0x4f, 0xec, 0x48, 0x91, 0x5d, 0x84, 0x2c, 0x74, + 0x25, 0x8f, 0xd3, 0x68, 0x65, 0x35, 0x65, 0x63, 0x20, 0xca, 0x47, 0x5a, + 0x34, 0xff, 0xf7, 0x3b, 0x44, 0xfd, 0x11, 0xe9, 0xf4, 0xac, 0x68, 0x78, + 0x9a, 0x31, 0x9c, 0xc1, 0x58, 0x6e, 0xb6, 0x9d, 0xb5, 0xa7, 0x30, 0x2b, + 0x32, 0xc3, 0xaa, 0xbb, 0x7f, 0xa5, 0x57, 0x1c, 0xc9, 0x9e, 0x85, 0x51, + 0x83, 0x93, 0xae, 0x8e, 0x0e, 0x3a, 0x0e, 0x0e, 0xac, 0xbc, 0xbc, 0x7c, + 0xbd, 0xf9, 0x14, 0xa4, 0x63, 0x0b, 0x61, 0x69, 0x69, 0x29, 0x3c, 0x3c, + 0x3c, 0x28, 0x6a, 0x40, 0x44, 0x4e, 0xce, 0x42, 0x18, 0x27, 0x4d, 0xa6, + 0x18, 0xd1, 0xf7, 0x97, 0x54, 0x91, 0xfb, 0xdd, 0x09, 0xde, 0xf4, 0xcc, + 0x4c, 0x7c, 0x5a, 0x5a, 0xc4, 0xe2, 0xa2, 0x86, 0x24, 0x39, 0x46, 0x43, + 0x99, 0xb6, 0xd0, 0xf7, 0xdd, 0xca, 0x8f, 0x43, 0x09, 0x3b, 0xbf, 0x9c, + 0xc1, 0x5f, 0x4b, 0x76, 0x79, 0x4e, 0xbc, 0x8c, 0x07, 0xac, 0x62, 0x4b, + 0x0b, 0x33, 0x28, 0x43, 0x8c, 0x2b, 0x2a, 0x31, 0xd5, 0x3a, 0x2d, 0x90, + 0x68, 0x71, 0xa1, 0x66, 0xde, 0xc8, 0x11, 0xc1, 0xc1, 0xd0, 0x0d, 0xb5, + 0x71, 0x12, 0x7d, 0xf4, 0xe5, 0xbc, 0x0c, 0xf9, 0x54, 0x55, 0x6b, 0xb1, + 0x3d, 0x31, 0xcf, 0xb5, 0x34, 0x69, 0x32, 0x77, 0x5b, 0x98, 0x0c, 0x0b, + 0xfb, 0xc4, 0x2d, 0x7c, 0x4f, 0x11, 0x44, 0xaa, 0x64, 0x6c, 0x4a, 0xe1, + 0xa3, 0x1d, 0xf1, 0x5b, 0x5b, 0x57, 0x09, 0x97, 0x51, 0xb8, 0x39, 0xde, + 0x7d, 0x4c, 0xdc, 0xac, 0x8a, 0xc5, 0x49, 0xff, 0xfd, 0xec, 0xd4, 0x65, + 0xb6, 0x5b, 0xb6, 0xd7, 0x48, 0x55, 0x5d, 0xfb, 0x7c, 0xc4, 0x1e, 0x22, + 0x46, 0xfa, 0x72, 0x7b, 0x4e, 0x41, 0xc8, 0xe7, 0x82, 0xc7, 0xa8, 0xa7, + 0xa6, 0xcb, 0x35, 0x30, 0x3d, 0x8d, 0x01, 0xd8, 0xea, 0xee, 0x60, 0x04, + 0x4c, 0x40, 0x2e, 0xf3, 0xd9, 0x5f, 0x9d, 0x9c, 0x9c, 0x1c, 0x4e, 0x16, + 0x99, 0x09, 0x79, 0x9c, 0xe1, 0x87, 0xe2, 0x88, 0xd5, 0x8f, 0x73, 0x50, + 0x12, 0xa1, 0xbf, 0x84, 0xdc, 0x1f, 0x05, 0xa3, 0x15, 0x23, 0x87, 0x74, + 0xc4, 0xf8, 0xd2, 0x2c, 0xf0, 0x4b, 0x7b, 0x47, 0xc4, 0xd7, 0x75, 0x2a, + 0xc4, 0xc0, 0xa1, 0xe0, 0x07, 0x93, 0x49, 0xc4, 0x1e, 0x88, 0xa5, 0x0c, + 0xfa, 0x2b, 0x95, 0x06, 0x37, 0x35, 0x71, 0x66, 0xf3, 0x7d, 0x6d, 0x70, + 0x19, 0xf2, 0x7d, 0xc4, 0xa0, 0x4f, 0x5f, 0x3a, 0x50, 0x2c, 0x6f, 0x25, + 0x49, 0x1a, 0xfe, 0xd8, 0xde, 0x77, 0xb8, 0x95, 0x8b, 0x96, 0x12, 0x57, + 0x1c, 0x74, 0xc3, 0x1b, 0xe4, 0x00, 0x49, 0x7e, 0xa9, 0x72, 0x0b, 0x54, + 0x23, 0x81, 0xed, 0xf8, 0xb4, 0x75, 0xda, 0x11, 0xf6, 0xfa, 0x70, 0xb9, + 0x22, 0x98, 0x38, 0x32, 0x16, 0x5f, 0x6d, 0xc2, 0xa1, 0xb6, 0xf7, 0x70, + 0xd2, 0x17, 0x71, 0x40, 0xb4, 0xa1, 0x5c, 0xe9, 0xa5, 0x4b, 0x17, 0x6f, + 0x74, 0x1f, 0x50, 0xb7, 0xe8, 0x73, 0x61, 0x1d, 0x92, 0xbe, 0x2b, 0x34, + 0xfc, 0xb5, 0x5d, 0xb9, 0x44, 0xee, 0xe2, 0xee, 0x4e, 0x5c, 0x41, 0x01, + 0xbd, 0xd5, 0xed, 0x1c, 0x55, 0x59, 0x79, 0x46, 0x4a, 0x6d, 0x9a, 0x08, + 0x80, 0x29, 0x2a, 0xf9, 0xec, 0xfe, 0x1c, 0xbf, 0xb7, 0x08, 0x28, 0x38, + 0x54, 0x21, 0x4a, 0x5a, 0x59, 0x17, 0x4c, 0xc4, 0x07, 0x30, 0x7b, 0x0d, + 0x5c, 0x71, 0xf4, 0x89, 0xba, 0x09, 0x92, 0xb4, 0xae, 0xf0, 0x0c, 0x9b, + 0xc8, 0xba, 0x56, 0x70, 0x7b, 0xe0, 0x2f, 0x1a, 0x4b, 0x2c, 0xb1, 0xcd, + 0x81, 0x28, 0x5c, 0x7b, 0x67, 0xe7, 0x0a, 0x75, 0x7e, 0x7c, 0x24, 0x80, + 0x47, 0x45, 0x00, 0x26, 0x56, 0x31, 0x06, 0xb4, 0x37, 0x73, 0xed, 0x36, + 0x49, 0x58, 0x3d, 0xb2, 0x1c, 0xe1, 0xeb, 0xa1, 0x26, 0x98, 0x65, 0xbb, + 0x8e, 0x25, 0xfe, 0x1c, 0x94, 0x72, 0x7c, 0x95, 0xa6, 0x93, 0xfd, 0x20, + 0xc6, 0x5e, 0xfd, 0x09, 0xbe, 0xe1, 0xa3, 0x36, 0x58, 0x5e, 0x5e, 0x5c, + 0x49, 0x39, 0x5c, 0x87, 0x61, 0x8b, 0x58, 0x6c, 0x9e, 0xac, 0xd2, 0xaa, + 0x4b, 0x08, 0x7c, 0xb5, 0xf8, 0x71, 0xd7, 0xce, 0xfe, 0xce, 0xf9, 0x72, + 0xe9, 0xb5, 0x7c, 0x8e, 0x41, 0x13, 0x7c, 0x87, 0x30, 0x63, 0x58, 0x0f, + 0x51, 0x29, 0xce, 0x7e, 0x1e, 0xdd, 0x75, 0xac, 0xb5, 0x5e, 0x62, 0x39, + 0x59, 0x6d, 0xc3, 0xb5, 0xeb, 0xb8, 0xc5, 0xf1, 0xbc, 0x3b, 0x41, 0x40, + 0x43, 0x43, 0xcb, 0xe2, 0x3c, 0x77, 0xef, 0x68, 0x4a, 0x49, 0xc1, 0x15, + 0x8f, 0x25, 0x8c, 0xc0, 0x63, 0x35, 0xcd, 0xad, 0xa9, 0x41, 0x57, 0x54, + 0x54, 0xcc, 0xb5, 0xc0, 0x77, 0x0c, 0xc1, 0xb8, 0x27, 0xe6, 0x1f, 0x1a, + 0x8e, 0x6a, 0xda, 0xf8, 0x37, 0x88, 0x3d, 0x6e, 0x4d, 0xab, 0x46, 0x34, + 0x83, 0x0d, 0xc4, 0x3b, 0x1f, 0x44, 0x65, 0x49, 0x14, 0xed, 0xef, 0x0f, + 0xaa, 0x07, 0x4c, 0xd4, 0x9a, 0xb3, 0xb9, 0xcc, 0xc9, 0x4a, 0x0b, 0x26, + 0x2e, 0x83, 0x8e, 0x42, 0x8c, 0x76, 0x1b, 0xb7, 0x91, 0x46, 0x97, 0xed, + 0x93, 0xb2, 0xa4, 0x74, 0x6a, 0x1a, 0x7c, 0x7c, 0x5a, 0x42, 0xb5, 0xab, + 0x89, 0xd8, 0x8c, 0x18, 0x3f, 0x00, 0xee, 0x08, 0x52, 0x26, 0x8d, 0x67, + 0xff, 0x96, 0x3e, 0xa5, 0x23, 0xf7, 0xe7, 0x72, 0x92, 0xbe, 0xbc, 0xca, + 0xd7, 0x18, 0x1b, 0xed, 0x55, 0xa9, 0x53, 0x2b, 0xa9, 0xcc, 0xad, 0x8b, + 0xa3, 0xc2, 0x0f, 0xa6, 0x0f, 0xb0, 0x1a, 0xd8, 0x5a, 0xea, 0xec, 0x7a, + 0xb5, 0x3c, 0x8a, 0x2d, 0xde, 0x1c, 0x0b, 0x57, 0xac, 0xb6, 0x56, 0x4f, + 0x2b, 0x7b, 0xd8, 0xdb, 0x33, 0x7d, 0xec, 0x27, 0x0c, 0x27, 0x50, 0x05, + 0x8d, 0x56, 0xbe, 0xfd, 0xd5, 0x5d, 0x48, 0x4d, 0x4f, 0x07, 0xe6, 0x2a, + 0xe4, 0xf6, 0x60, 0xcc, 0x37, 0x60, 0xee, 0x64, 0x0b, 0xf8, 0x20, 0x82, + 0xa8, 0x31, 0x22, 0x1c, 0x6e, 0x4e, 0xd8, 0xed, 0x9b, 0x09, 0x1f, 0xbc, + 0x1a, 0x2a, 0x9a, 0x94, 0x75, 0xe5, 0x7c, 0x49, 0xaa, 0x56, 0x18, 0x5c, + 0x4a, 0xb4, 0xb4, 0xb4, 0x8c, 0x2e, 0x36, 0x7a, 0x6e, 0xff, 0xb8, 0x19, + 0x6f, 0x01, 0xa8, 0x93, 0x2a, 0xe0, 0xd3, 0x5a, 0x16, 0x5c, 0x15, 0x51, + 0x0b, 0x2a, 0xc7, 0x95, 0xb5, 0x62, 0x8b, 0xf1, 0x5f, 0x7e, 0xae, 0xef, + 0x05, 0x44, 0x45, 0x41, 0x81, 0xda, 0x93, 0xc2, 0x90, 0x3a, 0x1d, 0xc7, + 0x05, 0x4a, 0xeb, 0x05, 0x7a, 0x27, 0xa1, 0xb1, 0x0c, 0xba, 0x72, 0xb2, + 0xc6, 0x47, 0x33, 0x98, 0xa5, 0xb9, 0xe6, 0xd1, 0x7b, 0x9e, 0xa1, 0x94, + 0xcd, 0x77, 0xc5, 0x6a, 0x78, 0xb1, 0xa7, 0xa3, 0xe6, 0x20, 0x6b, 0xca, + 0xd2, 0x65, 0x68, 0xb4, 0x97, 0x09, 0xf9, 0xaf, 0x4e, 0x67, 0xd4, 0xbb, + 0xcd, 0x72, 0x50, 0xa0, 0x14, 0x72, 0x4b, 0x50, 0x10, 0x14, 0x2a, 0x11, + 0xdf, 0xef, 0x64, 0xf1, 0x1f, 0x92, 0x4c, 0xc8, 0x41, 0x40, 0xf5, 0x19, + 0xac, 0xb5, 0x7b, 0xb8, 0xbf, 0xb5, 0xd7, 0x4b, 0xb4, 0x14, 0xb5, 0x20, + 0x54, 0xd0, 0x8d, 0x31, 0x19, 0x6a, 0x80, 0x43, 0x6f, 0xe7, 0x4e, 0x11, + 0x18, 0x29, 0xe8, 0x09, 0x82, 0x8a, 0xfd, 0xca, 0x68, 0x2a, 0xb6, 0x4e, + 0x4e, 0xa2, 0x1f, 0x1e, 0x1e, 0x60, 0x95, 0x91, 0x07, 0x14, 0x16, 0xff, + 0x98, 0x20, 0x7d, 0x6c, 0x0e, 0xe0, 0xcb, 0x13, 0xae, 0x11, 0x20, 0x99, + 0x46, 0x57, 0xec, 0xc5, 0x84, 0x4a, 0x8c, 0xcd, 0x88, 0xca, 0x68, 0x36, + 0xa3, 0xfe, 0x61, 0xc1, 0x23, 0x25, 0x8c, 0xf5, 0x21, 0x17, 0xf3, 0x08, + 0x1e, 0xd9, 0x8d, 0x0f, 0xd5, 0x47, 0x8d, 0x33, 0xb8, 0x00, 0x80, 0x80, + 0xcc, 0x7f, 0xc0, 0xd1, 0x15, 0x16, 0x11, 0x8d, 0x16, 0xab, 0x74, 0x93, + 0xc2, 0x18, 0x47, 0xc0, 0xc3, 0x8e, 0xf0, 0x03, 0xb4, 0xa5, 0x8c, 0xe5, + 0x58, 0x91, 0x1b, 0xdf, 0x3d, 0x20, 0xcb, 0x39, 0xde, 0x51, 0x2d, 0x28, + 0x76, 0xd5, 0x83, 0x82, 0x82, 0x1c, 0x00, 0xc3, 0x17, 0x54, 0x25, 0x2f, + 0xa7, 0x88, 0x05, 0x0c, 0x69, 0x66, 0x9f, 0x27, 0x67, 0x60, 0x54, 0x12, + 0x70, 0xda, 0x0a, 0x95, 0xaa, 0x88, 0x90, 0x26, 0x91, 0x70, 0x76, 0xa1, + 0xe3, 0x56, 0x0b, 0x0a, 0x49, 0x9b, 0xc1, 0xd5, 0x3b, 0x5a, 0x54, 0xb1, + 0x7e, 0x1e, 0x93, 0x09, 0x6e, 0x76, 0xde, 0x0e, 0xa0, 0x59, 0xe7, 0x12, + 0x14, 0x24, 0xd6, 0x6d, 0x73, 0x0d, 0x69, 0x6b, 0x6b, 0xfb, 0x7b, 0x67, + 0x1d, 0xed, 0x7d, 0x39, 0x80, 0x5b, 0x66, 0xc0, 0x85, 0x23, 0xb6, 0x79, + 0xed, 0x91, 0xb0, 0x0e, 0x6e, 0x5e, 0x9a, 0xac, 0x69, 0x68, 0x04, 0x0d, + 0xe4, 0xdb, 0x6f, 0xbf, 0x19, 0x27, 0x45, 0x17, 0x47, 0x65, 0x7d, 0x95, + 0x8a, 0xef, 0x61, 0x0a, 0xe1, 0xbc, 0xf9, 0x8d, 0x9f, 0x17, 0x2f, 0x14, + 0xfb, 0x09, 0x85, 0x90, 0x8c, 0xec, 0x1d, 0x82, 0x2d, 0xcb, 0x33, 0xc3, + 0xd0, 0x31, 0x28, 0xe0, 0xd7, 0x97, 0xda, 0x24, 0xa4, 0x12, 0x23, 0x67, + 0xf7, 0x38, 0x9a, 0xd5, 0xbf, 0x03, 0x46, 0x08, 0x02, 0xcf, 0x7b, 0xea, + 0xd6, 0x6f, 0xa7, 0x0a, 0x21, 0xbf, 0xb2, 0x00, 0xdc, 0xfe, 0x78, 0xff, + 0xbf, 0x39, 0x82, 0x71, 0x40, 0x0e, 0x0e, 0xdf, 0x18, 0x73, 0x61, 0x64, + 0x64, 0x64, 0x6a, 0x1c, 0x77, 0xa5, 0x56, 0x3a, 0x7d, 0x08, 0x20, 0x20, + 0x20, 0x68, 0xb8, 0xfb, 0x98, 0x34, 0xde, 0x6e, 0xab, 0x9b, 0xed, 0x75, + 0x9b, 0x6c, 0x68, 0xbd, 0x12, 0x69, 0x93, 0x9e, 0x4f, 0x9b, 0xd6, 0x8f, + 0x9c, 0xbb, 0x06, 0xc5, 0x1d, 0x1d, 0x59, 0x62, 0x89, 0x05, 0xab, 0xf0, + 0x9b, 0x6c, 0xb6, 0x61, 0xd5, 0x25, 0xbc, 0xf8, 0x2d, 0x0b, 0x79, 0x29, + 0xe3, 0x0e, 0x82, 0x5c, 0xd7, 0x2c, 0xc5, 0xf0, 0x85, 0x67, 0x5a, 0xa4, + 0x63, 0xa2, 0x21, 0xd9, 0x69, 0x7f, 0xca, 0x7f, 0x49, 0x0c, 0x00, 0xdf, + 0xc0, 0x46, 0xd1, 0x72, 0x11, 0x96, 0x38, 0x28, 0x1d, 0x16, 0x7c, 0xf3, + 0x5f, 0x81, 0x05, 0x45, 0xc3, 0x88, 0x2f, 0xde, 0xcd, 0x79, 0x23, 0x1f, + 0xe0, 0x69, 0xec, 0x6a, 0x7b, 0xc0, 0x0c, 0xb8, 0xbb, 0x0d, 0xbb, 0x71, + 0x39, 0xee, 0x69, 0x85, 0x98, 0x01, 0x8f, 0x74, 0xbf, 0x39, 0xf8, 0xb4, + 0xe6, 0xb1, 0xff, 0xb9, 0x06, 0xa5, 0x90, 0x54, 0xdb, 0xe6, 0xe2, 0xf2, + 0xb2, 0x07, 0x30, 0x8d, 0x97, 0xb7, 0x0b, 0xfa, 0x7d, 0x8b, 0xcd, 0xe4, + 0xa6, 0x42, 0xa4, 0x49, 0x9b, 0xdb, 0xd5, 0x8d, 0x9b, 0x97, 0xd7, 0x3f, + 0xb2, 0x4e, 0x79, 0xbf, 0x90, 0xa3, 0x9f, 0xb0, 0x30, 0xdc, 0xd5, 0x99, + 0x4d, 0x90, 0xf2, 0xf2, 0x6a, 0x9b, 0x3d, 0xb3, 0x73, 0xb8, 0x9e, 0xaf, + 0x55, 0xce, 0xfb, 0xba, 0xca, 0x88, 0xca, 0xbf, 0x7e, 0x2d, 0x30, 0x6e, + 0x26, 0x44, 0x55, 0x63, 0x4c, 0x47, 0xb5, 0x42, 0x62, 0x4d, 0x8a, 0x36, + 0xec, 0x1f, 0x2f, 0x9c, 0xa6, 0x12, 0x3c, 0x56, 0xa4, 0x17, 0x21, 0xfb, + 0x08, 0x09, 0x3e, 0x67, 0x3d, 0x1b, 0xe9, 0xc7, 0xb9, 0x02, 0xf5, 0xaf, + 0x7b, 0xa6, 0xe8, 0x68, 0x24, 0xd0, 0x9e, 0x29, 0xe5, 0xc3, 0xe6, 0x28, + 0xf7, 0xc5, 0xe5, 0x6f, 0x1e, 0x5c, 0xbe, 0xea, 0x1a, 0x70, 0x5d, 0xb2, + 0x4d, 0x7f, 0xd0, 0xd0, 0x25, 0x76, 0xf6, 0xed, 0xc9, 0x12, 0x26, 0xe0, + 0x94, 0xc4, 0xa3, 0x70, 0xe8, 0x9d, 0x4b, 0xdc, 0xf9, 0xbb, 0xb7, 0x2f, + 0x99, 0xec, 0xd6, 0xf8, 0x56, 0xda, 0x3d, 0x30, 0xdf, 0xde, 0xde, 0x40, + 0xa0, 0x52, 0x95, 0xd8, 0xfb, 0x14, 0x9b, 0xde, 0x51, 0xe7, 0x55, 0xb0, + 0xe6, 0x3e, 0x8e, 0x2b, 0xfc, 0xf1, 0xbc, 0x1e, 0x7b, 0xf2, 0xe8, 0x2e, + 0x97, 0xcf, 0x53, 0xbd, 0xdc, 0x9d, 0xa5, 0xf5, 0x24, 0x5b, 0xcc, 0xb7, + 0x30, 0xd4, 0xd2, 0xc1, 0xbd, 0xe2, 0xc1, 0x83, 0x99, 0xca, 0x20, 0x22, + 0xf6, 0x69, 0x7e, 0x54, 0x57, 0xb5, 0xc5, 0x9a, 0x93, 0xcf, 0x0d, 0xf9, + 0x72, 0xc8, 0x09, 0xc4, 0x3d, 0xfb, 0x4d, 0x9e, 0xda, 0x71, 0x96, 0x9f, + 0xf0, 0x21, 0x80, 0xd6, 0x64, 0x6a, 0xef, 0x50, 0xa6, 0x4e, 0xa3, 0xf3, + 0xc0, 0x53, 0xe0, 0x82, 0x31, 0xa0, 0xce, 0x2d, 0x94, 0x5e, 0x4e, 0x66, + 0x14, 0x0c, 0xee, 0x52, 0x1f, 0xa5, 0x59, 0xa7, 0xa5, 0xc6, 0xd8, 0xec, + 0x90, 0xe7, 0xdc, 0x52, 0xa4, 0x98, 0x5b, 0x0b, 0x45, 0xc6, 0x0b, 0xdc, + 0x1e, 0x8a, 0xeb, 0xeb, 0xcd, 0x77, 0x10, 0xc5, 0x82, 0xf2, 0x07, 0xe4, + 0x83, 0x94, 0x8c, 0xec, 0x13, 0x06, 0x06, 0x24, 0xe8, 0xbf, 0x91, 0xf1, + 0xa1, 0xe9, 0x5b, 0xde, 0x59, 0xc8, 0x5f, 0xf5, 0xc3, 0x63, 0x0e, 0x50, + 0x3d, 0xa6, 0x29, 0x6f, 0x3c, 0x59, 0x7c, 0x1e, 0x4a, 0x54, 0xcf, 0x6c, + 0x1c, 0xbe, 0xef, 0xaf, 0x6e, 0x3a, 0x6d, 0x6a, 0x47, 0xf4, 0x47, 0xcb, + 0x53, 0x70, 0x3a, 0xb6, 0xdb, 0x8c, 0x06, 0x4b, 0x7f, 0xcb, 0xb1, 0xd7, + 0x72, 0x0a, 0x93, 0x51, 0x84, 0x87, 0x7f, 0x1c, 0xd2, 0xca, 0xca, 0xf4, + 0x12, 0x4c, 0x30, 0x92, 0xe4, 0xad, 0x59, 0xb8, 0xfb, 0xce, 0x51, 0xca, + 0xe9, 0xad, 0x05, 0x3c, 0x4a, 0xed, 0x8e, 0x26, 0x55, 0x0f, 0xfd, 0xff, + 0x9d, 0x38, 0x37, 0x76, 0x0a, 0x16, 0x6c, 0x44, 0x0a, 0x81, 0x97, 0x17, + 0x38, 0x80, 0xcf, 0xcb, 0x2f, 0x2a, 0xcc, 0x26, 0xb2, 0xb9, 0xdc, 0x2f, + 0xbe, 0x00, 0xc0, 0xed, 0x5c, 0x50, 0x43, 0xb4, 0x79, 0xe9, 0xfe, 0xb1, + 0xbd, 0xf8, 0xf6, 0x7c, 0x2e, 0x48, 0x4e, 0x41, 0x41, 0x42, 0xcf, 0x0a, + 0x77, 0xb8, 0xe4, 0x01, 0x7f, 0x78, 0x52, 0x72, 0x5b, 0xcf, 0x01, 0x2c, + 0x40, 0xa1, 0xe9, 0xce, 0x17, 0x0e, 0x06, 0x04, 0xd0, 0x07, 0xbe, 0xc8, + 0x64, 0xf1, 0x60, 0x53, 0x52, 0xc6, 0xd0, 0xd6, 0x48, 0x67, 0x84, 0x0f, + 0x18, 0x45, 0x83, 0x99, 0x21, 0x3d, 0x3c, 0x3c, 0x40, 0x52, 0x81, 0x84, + 0x29, 0x7e, 0x5c, 0x10, 0x77, 0x1c, 0xa1, 0x0b, 0xba, 0xf2, 0xb8, 0x0f, + 0x8d, 0xae, 0x7d, 0x59, 0x07, 0x25, 0x26, 0x7c, 0x12, 0x2c, 0x79, 0x4a, + 0x69, 0x54, 0x06, 0xe0, 0x29, 0x84, 0x0e, 0x1a, 0x71, 0xf3, 0x1a, 0xa0, + 0xff, 0xa0, 0x02, 0x07, 0x1c, 0xeb, 0xd4, 0x69, 0x94, 0xdf, 0xef, 0x5b, + 0x13, 0x69, 0x73, 0x86, 0x06, 0x42, 0xe5, 0xd7, 0x7d, 0x8c, 0x3b, 0x8e, + 0x4f, 0x9f, 0xe5, 0x7e, 0x8b, 0xcd, 0x77, 0x16, 0x03, 0xf6, 0x99, 0xcb, + 0x7e, 0x43, 0xa8, 0x80, 0x6d, 0xaf, 0x9a, 0x99, 0x9d, 0x7d, 0x40, 0xf0, + 0xfd, 0x05, 0x8a, 0x97, 0x97, 0x17, 0xd4, 0xbd, 0x39, 0xa3, 0x5e, 0xb3, + 0xcd, 0xb8, 0x9a, 0x99, 0x5d, 0x12, 0x4d, 0x67, 0xf3, 0x43, 0x5d, 0x41, + 0xc1, 0x1f, 0x10, 0x5c, 0x21, 0xcd, 0x62, 0x1e, 0xb0, 0x70, 0x96, 0xbe, + 0xdf, 0xab, 0x6a, 0xa5, 0xeb, 0x73, 0x8d, 0xef, 0xea, 0xe4, 0xfc, 0x8c, + 0xac, 0x1f, 0xe2, 0x1c, 0xab, 0x35, 0x07, 0x12, 0x2d, 0xae, 0x9c, 0xea, + 0x33, 0x64, 0x81, 0xca, 0x5e, 0x4c, 0x09, 0xb5, 0xfa, 0x6a, 0xb2, 0x1e, + 0x39, 0x9b, 0xd6, 0x7f, 0x08, 0x1d, 0x01, 0x93, 0x15, 0x4b, 0x9e, 0x64, + 0xf1, 0x07, 0x27, 0xc2, 0xe9, 0x0c, 0x37, 0x20, 0x29, 0xa5, 0x99, 0x79, + 0x6f, 0x3e, 0x28, 0xfe, 0xc0, 0xb2, 0x6a, 0xa9, 0x3b, 0x80, 0x45, 0x04, + 0x74, 0xbb, 0xa0, 0x10, 0x43, 0x5a, 0x0d, 0x2d, 0x16, 0xaa, 0x3e, 0xcb, + 0x65, 0xf1, 0xc0, 0x48, 0x8f, 0x0e, 0xfa, 0xe1, 0xb3, 0x30, 0x33, 0x0b, + 0x1b, 0x18, 0x7c, 0xf1, 0x7d, 0xbd, 0x55, 0x07, 0x75, 0x9f, 0xc2, 0xc9, + 0x4f, 0x56, 0x16, 0xa0, 0x9d, 0xd4, 0xeb, 0x40, 0xad, 0xad, 0xcc, 0x82, + 0x35, 0x5b, 0x60, 0xdc, 0x5f, 0xf8, 0xf0, 0x90, 0xfb, 0x36, 0x0e, 0x67, + 0x4a, 0x14, 0x68, 0x92, 0xe0, 0x51, 0x50, 0xe6, 0x8e, 0x04, 0x62, 0x02, + 0x1e, 0x1e, 0xdc, 0x3f, 0x4e, 0x9c, 0x54, 0x07, 0x53, 0xf2, 0xfd, 0x07, + 0xea, 0x06, 0xf3, 0xd3, 0x6c, 0xb6, 0xdf, 0x3d, 0xe8, 0xa2, 0x22, 0x14, + 0x40, 0xeb, 0xf3, 0x55, 0x5c, 0x8e, 0x77, 0x34, 0x52, 0x18, 0x72, 0xe6, + 0x24, 0x61, 0x7d, 0x25, 0xe6, 0xad, 0x0f, 0x15, 0x9d, 0x2e, 0x64, 0x6c, + 0x7c, 0xe1, 0xc2, 0x76, 0x20, 0x2e, 0xae, 0x0a, 0xdc, 0xc2, 0x22, 0x9f, + 0xc6, 0x2c, 0xc3, 0x2b, 0x32, 0x7f, 0x0c, 0xe3, 0x4e, 0xeb, 0xbf, 0xd0, + 0xc8, 0x27, 0xaa, 0x3e, 0x3d, 0x29, 0xf5, 0x63, 0x3a, 0x63, 0x5a, 0x8d, + 0xdf, 0xe7, 0xea, 0x9e, 0xd9, 0x03, 0x02, 0x02, 0xb8, 0x3c, 0xae, 0x7e, + 0x24, 0x58, 0xde, 0x1e, 0x1e, 0x1d, 0x45, 0x02, 0x40, 0xdc, 0x3f, 0x34, + 0x14, 0x64, 0x08, 0x5e, 0x89, 0xf3, 0xf9, 0xb8, 0x5f, 0xa6, 0xd5, 0x51, + 0x5d, 0x44, 0x8d, 0x48, 0x92, 0xf5, 0xd2, 0xbd, 0xeb, 0x68, 0xff, 0xaa, + 0xf7, 0x3d, 0xac, 0x12, 0xf8, 0xc4, 0xe2, 0xf2, 0x32, 0x29, 0x53, 0xcd, + 0xd1, 0x58, 0x50, 0x31, 0x6c, 0x1f, 0xd3, 0xc7, 0xc5, 0x81, 0xfc, 0x7c, + 0xa9, 0x69, 0x84, 0x47, 0x3e, 0x86, 0xe4, 0xf6, 0x77, 0x1c, 0x4f, 0x97, + 0xcb, 0x85, 0x3a, 0xd3, 0xa7, 0x9e, 0x9e, 0xbf, 0x88, 0x9c, 0x67, 0x82, + 0xc2, 0x96, 0xe2, 0x11, 0xc7, 0x59, 0xc5, 0x45, 0x6f, 0x74, 0xc9, 0xd7, + 0x72, 0xa1, 0xc3, 0xb4, 0xd3, 0x75, 0x96, 0xc1, 0xb0, 0xb0, 0xcc, 0x07, + 0xb0, 0x71, 0xb4, 0xfd, 0x5b, 0x48, 0xcf, 0x78, 0x94, 0x76, 0xb3, 0x56, + 0xc3, 0x15, 0x08, 0x9f, 0x52, 0x99, 0xea, 0x9f, 0x94, 0xf5, 0xd5, 0x6c, + 0x21, 0x4c, 0xbd, 0x5f, 0x5c, 0x42, 0xe4, 0x2c, 0x88, 0x88, 0x88, 0xb8, + 0xfc, 0xde, 0xf8, 0xac, 0xad, 0xf1, 0x6d, 0xe1, 0x68, 0x65, 0x2f, 0x2f, + 0x2e, 0xba, 0xef, 0x4e, 0xff, 0x41, 0x80, 0x5a, 0x1e, 0x43, 0xdc, 0xb1, + 0x52, 0x82, 0x05, 0x56, 0x79, 0xcd, 0xf9, 0xc5, 0x26, 0x46, 0x57, 0xf1, + 0xcc, 0xaa, 0x57, 0x54, 0xd9, 0x6d, 0xb8, 0x7d, 0x5f, 0xb8, 0x76, 0x1c, + 0xb9, 0x3d, 0x6f, 0x8f, 0xe6, 0x36, 0x08, 0x62, 0xcc, 0x83, 0xec, 0x3a, + 0x1f, 0x61, 0x01, 0x5d, 0x55, 0x89, 0xe9, 0xd2, 0x61, 0xc2, 0x0e, 0xf2, + 0x72, 0x9b, 0x2a, 0x10, 0x7f, 0x0a, 0x1b, 0x37, 0xdd, 0x5c, 0x49, 0xf2, + 0xaa, 0x16, 0x67, 0xcb, 0x19, 0xdf, 0xf3, 0x98, 0x76, 0xbe, 0x3c, 0xf7, + 0x54, 0x8d, 0x9c, 0xdc, 0xf8, 0x02, 0xbb, 0xda, 0xbd, 0x69, 0x1f, 0xbd, + 0x47, 0x9b, 0x74, 0xe8, 0xa4, 0x17, 0xd7, 0xd7, 0xda, 0x30, 0xb4, 0xa5, + 0x69, 0x5c, 0xce, 0x8e, 0x8c, 0x18, 0x82, 0x71, 0x4e, 0xff, 0x2f, 0x98, + 0xea, 0xf2, 0xa8, 0x65, 0x81, 0x83, 0x83, 0x03, 0xe8, 0x5f, 0xb6, 0xcc, + 0x2c, 0x02, 0xdb, 0xb8, 0xc3, 0xd6, 0x8d, 0xff, 0x79, 0x99, 0xb2, 0x33, + 0x9b, 0x04, 0x25, 0xd6, 0x4b, 0x72, 0x01, 0x98, 0x8e, 0xb6, 0x06, 0xf5, + 0x28, 0x85, 0x6a, 0x5a, 0x42, 0x54, 0x82, 0xcf, 0xff, 0x3c, 0x37, 0x66, + 0x07, 0xfe, 0x95, 0x51, 0x72, 0x7e, 0xd0, 0x83, 0xa5, 0x25, 0x0d, 0x2c, + 0x0a, 0xfe, 0xec, 0x8f, 0x18, 0x9e, 0x3e, 0xa6, 0x07, 0xa0, 0x13, 0x6a, + 0x0d, 0x7a, 0x20, 0x55, 0x85, 0x0b, 0xe2, 0xa1, 0xbc, 0x0c, 0x96, 0x7f, + 0xbf, 0x79, 0x9e, 0x5a, 0xd9, 0xc1, 0x37, 0xd7, 0xd7, 0x0c, 0x05, 0x60, + 0xa6, 0x90, 0x24, 0x27, 0x26, 0xba, 0x94, 0x58, 0xc4, 0xb7, 0xc5, 0x2b, + 0x2e, 0x08, 0x62, 0x45, 0x92, 0x2b, 0x4d, 0xfa, 0x2b, 0x18, 0x87, 0x0b, + 0x73, 0x1a, 0x68, 0xd0, 0x51, 0x49, 0x14, 0xb1, 0x5c, 0xdb, 0xf9, 0xef, + 0x41, 0xf8, 0x3b, 0x39, 0xf1, 0x5a, 0x3f, 0x79, 0x73, 0x44, 0xbb, 0xcf, + 0x71, 0x4a, 0x2e, 0xf9, 0xbd, 0x60, 0xdc, 0x11, 0x77, 0x15, 0x52, 0x5e, + 0x5f, 0x5d, 0xf5, 0x76, 0xbd, 0xbf, 0x21, 0xd9, 0xd9, 0xd9, 0xad, 0x7e, + 0xd5, 0x89, 0x23, 0xa7, 0xa4, 0xdc, 0x9a, 0x91, 0x17, 0x1c, 0x78, 0x79, + 0xbc, 0xbe, 0xbc, 0xd8, 0xfc, 0xc6, 0xe7, 0xfb, 0x02, 0x9e, 0x9a, 0x9a, + 0x92, 0x94, 0x91, 0xe9, 0x07, 0x54, 0x71, 0x63, 0x63, 0x43, 0xc1, 0x82, + 0xaa, 0x39, 0x37, 0xf7, 0xcb, 0x87, 0xf9, 0x36, 0x51, 0xc0, 0x50, 0x9e, + 0x36, 0x34, 0x36, 0x81, 0x05, 0x2a, 0x48, 0x6b, 0x6e, 0x62, 0xb9, 0x17, + 0x19, 0xf0, 0x61, 0x97, 0xe7, 0x21, 0x04, 0x65, 0x1d, 0xb6, 0xeb, 0x9d, + 0x28, 0xa8, 0x61, 0x05, 0xf3, 0xa4, 0xf5, 0xa5, 0x3f, 0x33, 0x32, 0xa2, + 0x14, 0x0b, 0xc4, 0x0d, 0x81, 0x21, 0x5f, 0xe6, 0x17, 0xb7, 0xf9, 0x1a, + 0x54, 0xbb, 0xd3, 0xe1, 0x60, 0x50, 0x9b, 0xde, 0xcc, 0x0e, 0xd7, 0x6d, + 0x58, 0x07, 0x00, 0x9c, 0x03, 0xab, 0x14, 0x76, 0xbb, 0x14, 0x73, 0x34, + 0x5d, 0x90, 0x61, 0x24, 0xe3, 0x91, 0x32, 0xa3, 0x48, 0x5f, 0xe0, 0x0b, + 0x25, 0x1e, 0xb5, 0x8e, 0x2d, 0x67, 0x9e, 0x12, 0xde, 0xe7, 0xef, 0x33, + 0x1e, 0xa7, 0x10, 0x42, 0xdd, 0xfb, 0x86, 0xfb, 0xa1, 0x71, 0x1b, 0x4b, + 0xd3, 0xa5, 0xcb, 0xf7, 0x58, 0x52, 0x14, 0xe2, 0x7f, 0x9f, 0x20, 0x11, + 0x86, 0x0f, 0x69, 0xd2, 0x32, 0x32, 0x08, 0x6c, 0x57, 0x5b, 0x61, 0x68, + 0xcb, 0x9f, 0xac, 0xe8, 0xcb, 0x90, 0x00, 0xc3, 0x3f, 0x9e, 0xc1, 0x59, + 0x6b, 0xd8, 0x07, 0xfb, 0x41, 0x97, 0x4a, 0x16, 0x73, 0xb2, 0x65, 0x74, + 0xf4, 0xf4, 0x53, 0x80, 0x61, 0xa5, 0xd3, 0xef, 0x24, 0xd4, 0xd3, 0xd3, + 0xb3, 0x2c, 0xd9, 0x72, 0xd8, 0x1e, 0xdc, 0x8c, 0x13, 0x7c, 0x53, 0x88, + 0x01, 0x9c, 0xb7, 0x83, 0xc1, 0x31, 0x62, 0x56, 0x66, 0x66, 0xd7, 0xeb, + 0x2e, 0xf1, 0xc9, 0x8a, 0x9f, 0x14, 0x7b, 0x31, 0x35, 0x62, 0x18, 0xea, + 0xe7, 0x8f, 0xe3, 0xc1, 0xf9, 0x7b, 0x16, 0x95, 0xab, 0xeb, 0xeb, 0x4f, + 0xf8, 0xf8, 0x91, 0x80, 0xc1, 0xff, 0xfd, 0xe3, 0xe3, 0xba, 0x46, 0x64, + 0x0b, 0xe6, 0x77, 0xcc, 0x0c, 0x96, 0xf0, 0x7e, 0x25, 0xe4, 0xb4, 0x16, + 0x9d, 0x39, 0x5c, 0xd0, 0x06, 0x4e, 0x7a, 0xfa, 0xdd, 0xcd, 0x57, 0x3a, + 0xbe, 0xac, 0x42, 0xf5, 0x01, 0x78, 0x14, 0xd8, 0xab, 0x7f, 0x3f, 0x72, + 0xa9, 0x93, 0xe2, 0x38, 0x3b, 0x39, 0xf6, 0xac, 0x71, 0x90, 0xac, 0x04, + 0xd2, 0x1e, 0xc5, 0x8d, 0x51, 0x41, 0x25, 0x0c, 0x6b, 0x6a, 0xac, 0x7b, + 0x38, 0x38, 0x38, 0x1f, 0x22, 0x12, 0xc4, 0xb9, 0xf7, 0x71, 0x6c, 0x22, + 0xe0, 0xcd, 0xc5, 0xe3, 0x72, 0x14, 0x0c, 0xb8, 0x2c, 0x55, 0xab, 0xb1, + 0x80, 0x5f, 0x98, 0x9b, 0x00, 0x5f, 0x22, 0x10, 0x13, 0x13, 0xdf, 0x00, + 0xa3, 0x41, 0xbd, 0x5a, 0x4f, 0x95, 0x5f, 0xbb, 0xdd, 0xbd, 0x76, 0x79, + 0x25, 0x78, 0xe7, 0x86, 0xe5, 0x3e, 0x65, 0xd9, 0x64, 0xaf, 0x39, 0xc0, + 0xde, 0x91, 0x9a, 0x7e, 0x66, 0x9c, 0x09, 0xd9, 0xf4, 0x6f, 0x66, 0x04, + 0x20, 0x90, 0x96, 0x6b, 0x96, 0x7c, 0xd4, 0x58, 0x88, 0x32, 0x69, 0x2c, + 0x62, 0xe3, 0xa9, 0x19, 0x69, 0x88, 0x97, 0x9b, 0xb3, 0x86, 0xfd, 0xa9, + 0x29, 0xdf, 0xa8, 0x37, 0xb6, 0xb7, 0x35, 0x8d, 0x47, 0x24, 0x77, 0x8a, + 0x07, 0x06, 0x9a, 0xd6, 0xe6, 0x32, 0x44, 0x82, 0x61, 0xe1, 0x1e, 0x63, + 0x58, 0x84, 0x9a, 0x75, 0x9a, 0xf2, 0xd8, 0xb2, 0x58, 0x6f, 0x6f, 0xdd, + 0xe7, 0xfb, 0xc3, 0x39, 0x8b, 0x4b, 0x20, 0xfc, 0x65, 0xaa, 0x7e, 0xff, + 0x34, 0x7e, 0x7d, 0xbd, 0x5f, 0x2f, 0x97, 0xca, 0xe5, 0x10, 0x05, 0x6a, + 0xdf, 0xf7, 0xf9, 0x94, 0xf3, 0xe1, 0xf1, 0x71, 0x73, 0xa3, 0x27, 0x08, + 0xbf, 0xd2, 0xe1, 0x72, 0x4b, 0x0c, 0x1a, 0x0e, 0xce, 0xf8, 0x78, 0xbe, + 0xd2, 0x00, 0x0c, 0xeb, 0xeb, 0xeb, 0x7b, 0x30, 0x5b, 0x9a, 0xb0, 0x9c, + 0x79, 0xfb, 0xef, 0x2d, 0xb0, 0xf0, 0x57, 0x95, 0x93, 0xcb, 0x80, 0x86, + 0x41, 0x30, 0xf6, 0x35, 0x65, 0x29, 0x5e, 0xf5, 0xcd, 0x8d, 0x33, 0x60, + 0x80, 0x49, 0xd9, 0xd9, 0x55, 0x8f, 0x9f, 0xf1, 0xf0, 0x01, 0xd2, 0xff, + 0x7d, 0xf1, 0x6e, 0xd3, 0x13, 0x1d, 0x5f, 0xd3, 0xc8, 0x56, 0xbe, 0x15, + 0x53, 0x2c, 0xab, 0xb1, 0x70, 0x67, 0xd9, 0x70, 0x62, 0xa1, 0xc5, 0x06, + 0x61, 0x4f, 0x91, 0x33, 0x13, 0x8c, 0x2f, 0xec, 0xab, 0x80, 0x8c, 0xcc, + 0x5a, 0x27, 0xf0, 0xd7, 0xd1, 0x63, 0x04, 0xc7, 0xdf, 0x14, 0x42, 0xc8, + 0xdd, 0xdc, 0x4c, 0xe6, 0xf3, 0x5c, 0xb5, 0xf8, 0xf9, 0x9b, 0xef, 0x03, + 0x5f, 0x36, 0x65, 0xe1, 0xef, 0x41, 0xe9, 0x14, 0x86, 0x01, 0x6d, 0xbb, + 0x8e, 0x22, 0x02, 0xb1, 0xe3, 0x00, 0xc0, 0xcc, 0x40, 0xc3, 0xc0, 0x18, + 0x5e, 0xed, 0x0c, 0x4b, 0xca, 0xcb, 0xfb, 0x5d, 0x23, 0xa9, 0x4e, 0x16, + 0x49, 0xe3, 0x52, 0x27, 0x49, 0x8d, 0xa5, 0xb3, 0x23, 0x01, 0x05, 0x09, + 0x2b, 0x3b, 0x93, 0xca, 0x6c, 0x1c, 0xba, 0x9c, 0x39, 0x1b, 0x4d, 0xf8, + 0xf2, 0x32, 0x74, 0x49, 0xa3, 0xf6, 0x9b, 0xe0, 0xb3, 0x0f, 0x7f, 0x8d, + 0xc5, 0xc0, 0xb3, 0xfd, 0xd7, 0x19, 0x61, 0x3a, 0x1e, 0x1e, 0x7c, 0x4c, + 0x2a, 0x39, 0x15, 0x2b, 0xa9, 0xe9, 0x45, 0x2e, 0xd7, 0x13, 0x30, 0x87, + 0xcd, 0x72, 0x21, 0x25, 0xc1, 0x5a, 0x97, 0x57, 0x42, 0x9c, 0x79, 0x35, + 0x2a, 0x60, 0xbe, 0xad, 0x5e, 0xbe, 0x5c, 0xa8, 0x38, 0xb0, 0x28, 0x99, + 0x71, 0x64, 0x90, 0x86, 0x20, 0xc3, 0xb3, 0x07, 0x42, 0x0f, 0xe0, 0x61, + 0x9d, 0xe9, 0x94, 0xde, 0x4c, 0x39, 0x08, 0x6d, 0x21, 0x80, 0x6c, 0xf8, + 0x75, 0x2f, 0xc7, 0xaf, 0x34, 0x37, 0x66, 0xbf, 0x54, 0x4a, 0x95, 0x16, + 0xd6, 0x3a, 0xbf, 0xa2, 0x62, 0xe1, 0x44, 0x41, 0x80, 0x36, 0x37, 0x37, + 0x17, 0x5b, 0x5d, 0xac, 0x82, 0x5c, 0xac, 0x88, 0x04, 0x7d, 0x09, 0x81, + 0xef, 0x2c, 0x93, 0xfa, 0xd9, 0x76, 0xef, 0xd7, 0xfd, 0xc2, 0x34, 0xe8, + 0x06, 0xfb, 0xc2, 0xd0, 0x1c, 0xae, 0xf7, 0x64, 0x53, 0x53, 0x53, 0x37, + 0x00, 0xb4, 0x19, 0xdc, 0x1b, 0xcf, 0x20, 0x89, 0x97, 0x54, 0xb9, 0x26, + 0x12, 0xf8, 0xde, 0xed, 0x9f, 0x2d, 0xcc, 0xc4, 0x8a, 0x3d, 0xef, 0x31, + 0x71, 0xc5, 0xc5, 0xd9, 0xd4, 0x37, 0x29, 0xa0, 0x1b, 0xff, 0x33, 0x33, + 0xe0, 0xa1, 0xf0, 0x57, 0x82, 0x87, 0xb7, 0x37, 0xdf, 0xd9, 0x7a, 0x57, + 0x5c, 0x78, 0x38, 0xfc, 0x85, 0x3b, 0x5f, 0xe5, 0x79, 0xa9, 0x7c, 0xec, + 0x67, 0xde, 0xd0, 0xa9, 0x02, 0x89, 0x6f, 0x0c, 0x29, 0xe5, 0x3f, 0x0a, + 0x7a, 0xbf, 0xd5, 0x38, 0xdf, 0x69, 0x1b, 0xb0, 0xdf, 0xfe, 0xbc, 0xe3, + 0x34, 0xe8, 0xdf, 0x27, 0xe1, 0x6d, 0x42, 0x47, 0xcb, 0x21, 0x6f, 0xff, + 0x35, 0x49, 0x27, 0xe4, 0x29, 0x94, 0xc3, 0xf3, 0x09, 0x1f, 0x16, 0xe5, + 0x7a, 0xa6, 0x33, 0xbe, 0xd7, 0x54, 0x5a, 0x1d, 0x62, 0x20, 0x0b, 0xe4, + 0x3f, 0xb4, 0xbb, 0xb1, 0xed, 0x36, 0x14, 0x38, 0x5a, 0xba, 0xe4, 0x56, + 0x35, 0x13, 0xdf, 0xa4, 0xca, 0x9e, 0xd7, 0xa2, 0xc3, 0xc0, 0x61, 0xbb, + 0xb2, 0xf8, 0x45, 0x3b, 0x17, 0x92, 0xc2, 0x65, 0x32, 0x0c, 0x85, 0x20, + 0x74, 0x65, 0x45, 0xa7, 0xb2, 0x82, 0xf3, 0xc7, 0x7f, 0xe8, 0xd1, 0xf8, + 0x45, 0x52, 0xdb, 0x43, 0x4d, 0xeb, 0xbe, 0x48, 0x0c, 0x29, 0x51, 0x97, + 0xdb, 0x43, 0xe5, 0xe3, 0x09, 0xc3, 0xd8, 0x8b, 0x4e, 0x92, 0x6e, 0x30, + 0xad, 0xd0, 0xe2, 0xde, 0x15, 0xba, 0x7c, 0x50, 0x09, 0xe2, 0x37, 0x8a, + 0x45, 0xc3, 0x9f, 0x05, 0xbc, 0xc1, 0x40, 0x2e, 0xad, 0xd9, 0x28, 0x8c, + 0x06, 0x8c, 0x98, 0x3f, 0x76, 0x85, 0x80, 0x68, 0xc3, 0x45, 0x49, 0x93, + 0x56, 0xa6, 0x7a, 0x70, 0xae, 0x8b, 0xd1, 0xa8, 0x06, 0xdb, 0x43, 0x65, + 0x18, 0xae, 0x59, 0x7b, 0x99, 0xa6, 0x37, 0xf9, 0xf4, 0xd4, 0x79, 0xf9, + 0xcb, 0x45, 0xcd, 0x41, 0xe8, 0x41, 0xb6, 0x5f, 0x6a, 0x96, 0xf4, 0xa0, + 0x12, 0x47, 0x12, 0x3d, 0xaa, 0x87, 0xce, 0x63, 0x89, 0xa1, 0xf5, 0xe5, + 0x17, 0xf0, 0x3b, 0xa4, 0x67, 0x90, 0x7d, 0x9f, 0xf7, 0xa3, 0x2d, 0xf9, + 0x6c, 0x57, 0xb8, 0xea, 0xad, 0x35, 0x5d, 0xf6, 0xd9, 0xbf, 0x99, 0x3d, + 0x5e, 0xed, 0xda, 0x21, 0x7b, 0x96, 0xa3, 0x70, 0x73, 0x73, 0x03, 0x73, + 0x3f, 0xd8, 0xf2, 0xe5, 0x6a, 0x57, 0x7a, 0xa5, 0xc3, 0x0b, 0xf7, 0xbc, + 0xe3, 0x5e, 0x0f, 0x06, 0x6d, 0x70, 0x8e, 0x37, 0xae, 0xbe, 0xd1, 0xce, + 0xa4, 0x66, 0x89, 0x6e, 0x2c, 0x47, 0x00, 0x52, 0x9f, 0x41, 0x21, 0x44, + 0x72, 0x03, 0x28, 0x55, 0xe0, 0xa3, 0xa2, 0x59, 0x55, 0xd8, 0xc8, 0x01, + 0xe5, 0xea, 0xd5, 0xbd, 0x13, 0x13, 0x68, 0xeb, 0xbe, 0xcf, 0x95, 0x34, + 0xec, 0x31, 0xa3, 0x86, 0x64, 0x15, 0xda, 0x5e, 0x1f, 0x27, 0x4d, 0x22, + 0x05, 0x91, 0x16, 0xc1, 0xc1, 0x23, 0x16, 0xa6, 0x56, 0x11, 0xb1, 0x36, + 0xda, 0x5d, 0xf8, 0xdf, 0x43, 0xa4, 0x4c, 0x4e, 0xaa, 0xd4, 0x2a, 0xd5, + 0x38, 0xd7, 0x8a, 0x91, 0xa0, 0x2b, 0x85, 0x90, 0x5b, 0x21, 0x36, 0x4e, + 0xf8, 0xfa, 0x32, 0x8b, 0x31, 0x9b, 0x20, 0xd9, 0x08, 0xa8, 0x4b, 0xd9, + 0x38, 0x1c, 0xdc, 0xcf, 0xf1, 0xbb, 0xfc, 0x9e, 0x37, 0x95, 0xfb, 0x13, + 0x2d, 0xa2, 0x9e, 0x36, 0xc3, 0x88, 0x2d, 0xf5, 0x87, 0x3d, 0x49, 0x19, + 0x18, 0x50, 0x9f, 0xef, 0x4e, 0x67, 0x1e, 0x05, 0xba, 0x5e, 0xae, 0x90, + 0xda, 0xdb, 0xdb, 0x27, 0x4b, 0xe4, 0x89, 0xd9, 0x3d, 0x1c, 0x2d, 0x61, + 0xaf, 0x90, 0xa2, 0x5c, 0x3a, 0xdf, 0xfd, 0xb3, 0x03, 0x52, 0x59, 0xfe, + 0xb0, 0x71, 0x7c, 0x1c, 0xba, 0x1f, 0x4c, 0x17, 0x21, 0xd9, 0xae, 0xb5, + 0x97, 0x5e, 0x77, 0x34, 0x7c, 0x57, 0x54, 0xfc, 0xf4, 0x71, 0xce, 0xac, + 0xaf, 0xaf, 0xef, 0x7c, 0x3c, 0x8f, 0x32, 0x91, 0xcd, 0x0f, 0x05, 0x02, + 0x23, 0xc5, 0x30, 0x99, 0xfc, 0xd0, 0x27, 0x7c, 0x7b, 0xf4, 0x5b, 0xac, + 0xb9, 0xf9, 0x5c, 0x5f, 0x63, 0xc7, 0x63, 0x12, 0xda, 0x00, 0x21, 0xa6, + 0x08, 0x7f, 0x3a, 0x2d, 0xc7, 0xae, 0x46, 0xe3, 0xf4, 0x44, 0x49, 0x69, + 0xab, 0x97, 0x27, 0x18, 0x03, 0x8f, 0x02, 0x61, 0x34, 0x89, 0xe2, 0x9f, + 0x98, 0x68, 0x2c, 0x0d, 0x16, 0xdf, 0x81, 0x06, 0x59, 0x73, 0x10, 0x48, + 0xaf, 0x11, 0xc3, 0x31, 0x94, 0x98, 0xb2, 0x0f, 0xe2, 0x85, 0xf6, 0xc8, + 0x77, 0x11, 0x2b, 0xc7, 0x74, 0x74, 0x74, 0x4c, 0xe5, 0x7d, 0x83, 0x5b, + 0xa5, 0xd6, 0x42, 0x7b, 0xb9, 0xe8, 0x43, 0xb3, 0xbc, 0xaf, 0x6a, 0x35, + 0x5a, 0xa8, 0xd2, 0xfd, 0x39, 0xfc, 0x03, 0x3b, 0x70, 0x1b, 0x4b, 0x0a, + 0x9f, 0x59, 0x5e, 0xff, 0xc0, 0xdb, 0x0f, 0x94, 0xca, 0x6a, 0x02, 0x4f, + 0x89, 0x8c, 0xa2, 0x1c, 0xb3, 0xbd, 0xbd, 0x3d, 0x55, 0xaa, 0x4c, 0xf5, + 0x41, 0x4c, 0x12, 0xb1, 0x84, 0x8a, 0x4e, 0x9a, 0x04, 0xa4, 0x40, 0xc2, + 0xe1, 0x11, 0x10, 0x7a, 0x7a, 0x43, 0x90, 0x3e, 0x7d, 0xfe, 0x8c, 0x12, + 0x6a, 0x68, 0x60, 0x4a, 0xda, 0x9f, 0xf9, 0xf5, 0x9b, 0xc3, 0xd6, 0xc2, + 0x5c, 0x2a, 0xaf, 0x0d, 0x17, 0xe1, 0x09, 0xbe, 0x6b, 0x6b, 0xa1, 0xc0, + 0xe1, 0xa7, 0x59, 0xb5, 0x4a, 0x8e, 0x40, 0x91, 0xf8, 0x3b, 0x88, 0x9c, + 0xf5, 0x58, 0x51, 0x2c, 0x8c, 0xb2, 0x60, 0xb0, 0x33, 0x7f, 0xdf, 0xae, + 0x67, 0xf3, 0xd7, 0xa4, 0x34, 0x1a, 0x75, 0x2f, 0xf3, 0x05, 0xd7, 0x86, + 0x32, 0x2d, 0x9c, 0x9c, 0xc4, 0xd0, 0x0c, 0x13, 0xad, 0x82, 0xbb, 0x63, + 0xf5, 0xba, 0x70, 0xf7, 0x6f, 0xa2, 0xa5, 0x2a, 0x5b, 0x0f, 0x0e, 0xab, + 0xa2, 0xe9, 0x29, 0x25, 0xff, 0x33, 0xa2, 0xf0, 0x68, 0x68, 0xd5, 0x93, + 0x85, 0x7b, 0x5d, 0xc7, 0x8a, 0xb7, 0xf9, 0x50, 0x51, 0x03, 0xbd, 0x81, + 0x69, 0x64, 0x97, 0x3d, 0x3b, 0x79, 0x1f, 0xc7, 0x33, 0x8b, 0x2d, 0x4e, + 0x54, 0xb0, 0x68, 0x44, 0xc8, 0xca, 0xca, 0xca, 0xce, 0x87, 0xd3, 0x30, + 0x40, 0xb2, 0x59, 0xc3, 0x79, 0x5d, 0x6b, 0x35, 0xa2, 0x01, 0x5e, 0xf8, + 0xb8, 0x32, 0x0a, 0x05, 0x8b, 0xec, 0x9f, 0x91, 0x91, 0xa1, 0xe5, 0xeb, + 0x91, 0xb3, 0x11, 0xcb, 0x75, 0x37, 0x9a, 0x92, 0xca, 0xd1, 0x2a, 0x28, + 0x13, 0x03, 0xe3, 0x39, 0x5b, 0xef, 0x30, 0xb9, 0xb2, 0x86, 0x0f, 0x41, + 0xd3, 0xc4, 0x0b, 0xa2, 0x0e, 0x66, 0x59, 0xaa, 0x53, 0xf5, 0x54, 0x0e, + 0x37, 0xb8, 0x40, 0x0f, 0xaa, 0x32, 0x33, 0xe7, 0xb9, 0x96, 0x16, 0xea, + 0x81, 0x91, 0xd2, 0x92, 0x8c, 0x25, 0xd0, 0x69, 0x83, 0x25, 0x6a, 0x22, + 0xe2, 0x53, 0x24, 0xe0, 0xdc, 0x69, 0xbb, 0x96, 0x88, 0x23, 0xda, 0x9c, + 0x22, 0x3b, 0x5d, 0x37, 0x24, 0xc0, 0xc3, 0x53, 0x7d, 0xb2, 0xc3, 0x27, + 0x26, 0x46, 0x0b, 0x10, 0xf2, 0x37, 0xec, 0x0b, 0x2d, 0x1d, 0x7e, 0x6f, + 0xf3, 0xd5, 0xa7, 0xe2, 0x3e, 0x4c, 0x12, 0x56, 0xc4, 0x2a, 0x8e, 0x3d, + 0x8a, 0x72, 0x1b, 0x42, 0x83, 0xec, 0xd2, 0xf9, 0xae, 0x9f, 0x5e, 0xec, + 0x70, 0xba, 0xcc, 0x1e, 0x8d, 0xc7, 0x0a, 0x0b, 0x50, 0xba, 0x46, 0x93, + 0xed, 0x67, 0x00, 0x91, 0x49, 0x70, 0xa2, 0x8e, 0xc5, 0x38, 0x73, 0x0b, + 0x99, 0xc6, 0x1e, 0xaf, 0xf7, 0x99, 0x3d, 0x6f, 0xcc, 0x3f, 0xb8, 0x86, + 0x8b, 0x0b, 0x2c, 0x9d, 0x4c, 0xd7, 0x13, 0x81, 0x49, 0xa5, 0xa0, 0xa0, + 0x00, 0xe2, 0x88, 0x0a, 0x21, 0xca, 0x7a, 0xa9, 0x39, 0x2d, 0x7f, 0xd4, + 0xa8, 0x73, 0x87, 0x95, 0x91, 0xad, 0xcf, 0x21, 0x99, 0x4c, 0x4c, 0xe3, + 0xf7, 0x08, 0xd7, 0xca, 0xf2, 0x0a, 0xfd, 0x04, 0x73, 0xfd, 0xd8, 0x49, + 0xf2, 0x34, 0x13, 0x6e, 0xf0, 0x1f, 0x10, 0xad, 0x44, 0xb0, 0x48, 0x8e, + 0x41, 0x11, 0x8b, 0xbe, 0x2a, 0xfe, 0x48, 0xb5, 0xac, 0xb4, 0xf3, 0x85, + 0x43, 0xf5, 0x1c, 0xfe, 0xe5, 0x77, 0x0b, 0xcb, 0xed, 0xf6, 0x76, 0xbe, + 0x53, 0xea, 0x12, 0x38, 0x3d, 0x38, 0x25, 0x0b, 0x28, 0x4e, 0x4e, 0x4e, + 0xeb, 0x7f, 0x8d, 0x28, 0x25, 0x72, 0x59, 0x22, 0xb6, 0xb6, 0x0c, 0x77, + 0xe7, 0xeb, 0xfa, 0x24, 0xa0, 0xb3, 0xb5, 0x8e, 0x5f, 0x47, 0xf6, 0x26, + 0x50, 0x7b, 0xfe, 0xbf, 0x32, 0x6f, 0xae, 0x1a, 0x2e, 0x5c, 0x10, 0x80, + 0xcc, 0xb6, 0x6d, 0xc3, 0x6d, 0x4e, 0x36, 0x4e, 0x5c, 0xfe, 0xd5, 0xde, + 0x64, 0xe2, 0x64, 0xaf, 0x62, 0xa2, 0x02, 0xa4, 0x10, 0x70, 0x1c, 0x22, + 0x80, 0x07, 0xaf, 0xa8, 0xa8, 0x40, 0x07, 0x83, 0xc3, 0x99, 0x8d, 0x07, + 0x0d, 0x0e, 0xa7, 0x8b, 0x9a, 0x5d, 0x8e, 0x93, 0xd5, 0xde, 0x4f, 0x81, + 0xd9, 0x39, 0x9a, 0xc2, 0xf8, 0x31, 0x3b, 0xeb, 0xad, 0x97, 0x30, 0xf2, + 0xf2, 0xf2, 0x1e, 0x8e, 0xab, 0xbb, 0x14, 0x74, 0x2a, 0x88, 0xb4, 0x27, + 0x1b, 0x0a, 0x38, 0xdf, 0x96, 0x5a, 0x21, 0x09, 0x04, 0xbd, 0xd0, 0x02, + 0x7c, 0x2b, 0xbf, 0x43, 0xb7, 0xa1, 0x5e, 0x58, 0x6d, 0x87, 0xda, 0x7e, + 0xf6, 0x19, 0x95, 0x34, 0x6f, 0x94, 0x49, 0xbe, 0xe1, 0xde, 0x28, 0x63, + 0x4c, 0x82, 0x87, 0x8d, 0xbe, 0x4b, 0x17, 0xc6, 0xb4, 0x14, 0x13, 0xea, + 0x46, 0xcb, 0xfc, 0xd7, 0x84, 0x6b, 0x07, 0x02, 0xab, 0xda, 0x6a, 0xbe, + 0xff, 0x5c, 0xbe, 0x1f, 0x53, 0xa3, 0x9e, 0xd5, 0xad, 0x5d, 0x96, 0xba, + 0x9d, 0x86, 0xfb, 0xfa, 0xf5, 0xab, 0x5d, 0xb6, 0x0a, 0x54, 0xb3, 0x0e, + 0x43, 0x95, 0x5e, 0x07, 0xa2, 0xd7, 0xf3, 0xb4, 0x08, 0x03, 0x20, 0x97, + 0x43, 0x35, 0x86, 0x7d, 0x17, 0x80, 0x7a, 0x96, 0xff, 0xa8, 0x5e, 0x5d, + 0x24, 0x21, 0x21, 0xa9, 0xa9, 0xaf, 0x57, 0x79, 0x6e, 0x6a, 0x7b, 0xdd, + 0x28, 0x5d, 0x7e, 0x75, 0xf5, 0x99, 0x1c, 0x9b, 0x47, 0xac, 0xa3, 0x14, + 0x35, 0x98, 0xed, 0x26, 0x5a, 0x6c, 0xbd, 0x07, 0xa3, 0x66, 0xb7, 0x42, + 0x7a, 0x50, 0x84, 0x98, 0x91, 0x63, 0x20, 0x00, 0x93, 0x3f, 0x44, 0xbb, + 0xc9, 0x16, 0x02, 0xa4, 0x56, 0xa9, 0x55, 0x54, 0xe6, 0xbb, 0xd0, 0xe9, + 0xe3, 0xf5, 0xd1, 0x64, 0xf4, 0x5a, 0xf5, 0xbf, 0x1d, 0xba, 0xbc, 0x5a, + 0x74, 0x62, 0x8f, 0x17, 0xaa, 0xb7, 0x01, 0x8e, 0x69, 0xf6, 0xbc, 0xa5, + 0xd1, 0x6b, 0x77, 0x0f, 0x38, 0x38, 0x38, 0xa0, 0xd9, 0xe7, 0xe5, 0x5e, + 0x34, 0x3a, 0xfa, 0xed, 0x0b, 0x5e, 0xae, 0x26, 0x60, 0xde, 0xe2, 0x09, + 0xcd, 0xa7, 0xf6, 0x16, 0xf0, 0x63, 0xa1, 0x1c, 0xd3, 0x8d, 0x01, 0x26, + 0x08, 0x08, 0xd4, 0xb7, 0x13, 0x06, 0x26, 0xe0, 0x8d, 0xa5, 0x65, 0x80, + 0xb5, 0xa8, 0x96, 0x52, 0x08, 0x02, 0x2a, 0xdc, 0xe1, 0xfe, 0x6c, 0x7f, + 0x1b, 0xaf, 0x58, 0xc8, 0xa4, 0x87, 0x9b, 0x90, 0xc3, 0xd3, 0xad, 0xda, + 0x87, 0x49, 0xdb, 0x33, 0xb9, 0x15, 0xc2, 0xcd, 0xc5, 0xa5, 0xb2, 0xce, + 0xf6, 0x29, 0xdf, 0xe3, 0x7a, 0x4f, 0x4b, 0x33, 0x6c, 0x68, 0xbb, 0x14, + 0xcf, 0x29, 0x77, 0x67, 0x36, 0x2d, 0xb9, 0xf8, 0x6c, 0xfc, 0xe2, 0x96, + 0x9e, 0xfb, 0x11, 0x1e, 0x1a, 0x52, 0x26, 0x9d, 0x0d, 0x61, 0xdd, 0xe7, + 0x3e, 0xeb, 0x68, 0xa9, 0xf2, 0xf7, 0xd0, 0x4f, 0xda, 0x44, 0xf6, 0x2a, + 0xa8, 0x5c, 0x59, 0xeb, 0x8a, 0xb1, 0x5a, 0x40, 0xcb, 0xc1, 0xd3, 0x25, + 0xb4, 0x6b, 0xba, 0x4f, 0x9f, 0x23, 0x45, 0xed, 0x5c, 0x6b, 0x25, 0xc4, + 0xc4, 0x48, 0x68, 0xca, 0x6e, 0xce, 0x72, 0x06, 0x8c, 0x02, 0x46, 0x77, + 0xf3, 0x01, 0xa3, 0x0e, 0x64, 0x40, 0x14, 0x50, 0x0e, 0xea, 0xc8, 0xc0, + 0x5a, 0x87, 0xc3, 0x43, 0x41, 0x6e, 0x6e, 0x3c, 0xc7, 0x16, 0xc2, 0x88, + 0x88, 0x08, 0x4b, 0x18, 0xd7, 0xb2, 0x5e, 0x51, 0xf3, 0x60, 0x46, 0x1c, + 0x19, 0xe1, 0x09, 0x39, 0x5f, 0x94, 0x46, 0x03, 0xc5, 0x6f, 0xfd, 0xcb, + 0xbd, 0x58, 0xe7, 0xf2, 0xf8, 0x81, 0xf2, 0x0b, 0xe7, 0x0a, 0xc3, 0x91, + 0x51, 0x39, 0x5e, 0x47, 0x8a, 0x14, 0x81, 0x01, 0x22, 0xc8, 0xad, 0x44, + 0x35, 0x0d, 0x59, 0x16, 0x89, 0x59, 0xaf, 0xcf, 0x29, 0x26, 0x26, 0x01, + 0xbe, 0xd9, 0x35, 0x0d, 0x2c, 0xd5, 0xb7, 0x5a, 0x45, 0x59, 0x69, 0x52, + 0xe6, 0xff, 0xb9, 0x1d, 0xb4, 0x9e, 0x60, 0x76, 0x1a, 0x0f, 0xa1, 0xea, + 0xb4, 0x38, 0x8a, 0xc9, 0xce, 0x97, 0xab, 0x33, 0xce, 0xe5, 0x00, 0xca, + 0x69, 0xd3, 0x30, 0x9f, 0xed, 0x2d, 0x80, 0x46, 0x48, 0x7f, 0x27, 0xb9, + 0x00, 0x08, 0xb5, 0x7a, 0x85, 0x16, 0x1b, 0x0a, 0x6d, 0xe7, 0x2b, 0x0a, + 0xb7, 0x47, 0x48, 0x83, 0x67, 0x4a, 0xb1, 0x85, 0x64, 0x91, 0x92, 0x4e, + 0x97, 0xaf, 0x2e, 0x6d, 0xab, 0x46, 0x6a, 0xda, 0xc7, 0x84, 0xf9, 0x5d, + 0xa4, 0xf4, 0xe9, 0x28, 0x6e, 0x6d, 0x75, 0xd9, 0xf8, 0x76, 0x6f, 0x5d, + 0x91, 0x8e, 0xe1, 0x71, 0x4b, 0x4c, 0x31, 0xd5, 0xdc, 0x12, 0xbf, 0xb1, + 0x2a, 0x77, 0xa3, 0xe2, 0xcc, 0x89, 0x0e, 0x01, 0x05, 0xd6, 0x68, 0xf2, + 0x56, 0x48, 0xee, 0x6f, 0x2d, 0x1e, 0x9b, 0xee, 0x8e, 0x86, 0xda, 0x7c, + 0x93, 0x84, 0x44, 0xcc, 0x3c, 0xcb, 0x57, 0x5c, 0xd9, 0x95, 0x45, 0xa9, + 0x70, 0xcb, 0x40, 0x51, 0x52, 0x61, 0x1d, 0x1d, 0x42, 0xad, 0x46, 0xeb, + 0x88, 0xde, 0x5e, 0x91, 0xfe, 0xfe, 0x7e, 0x83, 0xbf, 0x99, 0xdc, 0x96, + 0xf7, 0x63, 0xc0, 0x02, 0x2a, 0x5c, 0xc3, 0xbb, 0x7b, 0x79, 0xf5, 0x8d, + 0x8e, 0x22, 0x31, 0x33, 0x33, 0x53, 0x40, 0x9e, 0xea, 0x7e, 0x5f, 0x88, + 0x20, 0x12, 0xb6, 0xb9, 0x3c, 0x8f, 0x4d, 0x72, 0x7f, 0xe0, 0x82, 0x40, + 0x23, 0x1a, 0xfa, 0x46, 0x9a, 0xb0, 0xbd, 0xe3, 0xc7, 0x39, 0xc7, 0x73, + 0x64, 0x41, 0x80, 0x23, 0x56, 0xda, 0xa9, 0xd3, 0xc2, 0xc3, 0xfe, 0x0d, + 0x10, 0xa1, 0x54, 0x96, 0x7c, 0xc6, 0xe8, 0x90, 0xc2, 0xaa, 0x88, 0x4e, + 0xa6, 0xad, 0xeb, 0xc9, 0x96, 0x20, 0xdc, 0xbf, 0x7a, 0x9d, 0x48, 0x20, + 0x03, 0xb0, 0xc3, 0x68, 0x7e, 0x7e, 0x5b, 0x1d, 0x44, 0xc5, 0x54, 0xb5, + 0x29, 0xf4, 0xb7, 0x40, 0xf0, 0x8d, 0xa7, 0xf8, 0x17, 0xf8, 0x60, 0x51, + 0x8c, 0x02, 0xb5, 0xc7, 0x90, 0xd1, 0xcd, 0xdc, 0x38, 0xd8, 0x33, 0xd7, + 0xdc, 0xc2, 0x06, 0x4b, 0xcd, 0xe5, 0x06, 0xab, 0x66, 0x2a, 0xea, 0x3c, + 0x05, 0xde, 0x4f, 0xd3, 0x52, 0x45, 0x18, 0x67, 0x67, 0x73, 0x70, 0xb8, + 0x7b, 0x3b, 0x3b, 0xfe, 0xc5, 0x16, 0x0d, 0x57, 0xcd, 0x40, 0x53, 0xd0, + 0x04, 0x65, 0x67, 0xa9, 0xfb, 0x67, 0xb6, 0x8b, 0x04, 0x1d, 0x20, 0x9a, + 0x02, 0x93, 0xb8, 0xbb, 0x9a, 0x1d, 0xf2, 0x45, 0x4a, 0x29, 0xd5, 0x34, + 0xfa, 0x2c, 0xee, 0x7a, 0xe1, 0x6c, 0xbb, 0xb7, 0xe1, 0xb9, 0xd9, 0x97, + 0x11, 0x67, 0xa9, 0x05, 0xa6, 0x41, 0x2b, 0x2e, 0x9f, 0x5a, 0x01, 0x4b, + 0x28, 0x40, 0x24, 0x05, 0x75, 0xad, 0x86, 0x89, 0x13, 0x02, 0xf4, 0xe0, + 0xde, 0x9c, 0x2b, 0x0d, 0x67, 0xb7, 0xf8, 0x4f, 0x43, 0x48, 0xa8, 0xac, + 0x15, 0x8f, 0x70, 0x37, 0x88, 0x02, 0x4f, 0xfc, 0x8a, 0x68, 0xa3, 0x15, + 0x55, 0x32, 0xf7, 0xb6, 0x10, 0xa3, 0xa7, 0xfb, 0x0b, 0x6c, 0x47, 0xb6, + 0x22, 0x4d, 0xd4, 0x32, 0x4b, 0xb4, 0xe4, 0xf8, 0xf2, 0x43, 0x83, 0x43, + 0x50, 0x44, 0xcd, 0x9d, 0x47, 0x9b, 0x26, 0xf7, 0x63, 0x33, 0x2e, 0x66, + 0x09, 0x25, 0x2b, 0x33, 0x73, 0x69, 0x46, 0xa0, 0x67, 0xa1, 0xc9, 0x68, + 0xf2, 0xc1, 0x7a, 0x97, 0xa0, 0x5c, 0x26, 0x57, 0xde, 0x75, 0x07, 0x29, + 0x29, 0x29, 0xcd, 0x6c, 0x2b, 0x31, 0x97, 0xfd, 0x97, 0xce, 0xf7, 0x37, + 0x2f, 0x10, 0x85, 0xdb, 0x59, 0xc4, 0xd7, 0x43, 0x58, 0xc3, 0xc9, 0xd1, + 0xbe, 0x5d, 0xc7, 0x49, 0xce, 0x66, 0xb2, 0x27, 0x58, 0xb7, 0xe0, 0x5f, + 0xc5, 0xf1, 0xa9, 0xbf, 0x02, 0x16, 0xcd, 0x18, 0x15, 0xc8, 0x31, 0xb6, + 0x4d, 0x3c, 0x39, 0x1c, 0xaf, 0xa3, 0x0c, 0x2c, 0x6c, 0x21, 0xb5, 0x69, + 0x91, 0x34, 0x52, 0x09, 0xfa, 0x66, 0xc6, 0x11, 0x30, 0x4a, 0x91, 0x59, + 0x5a, 0x08, 0xe7, 0x93, 0x4d, 0x99, 0xd8, 0x71, 0x44, 0xa8, 0x37, 0x0a, + 0x34, 0xe8, 0x02, 0x92, 0x5a, 0xf0, 0x24, 0x75, 0xb4, 0xfb, 0xba, 0x35, + 0x72, 0xcf, 0x48, 0x0c, 0xc1, 0xf1, 0xac, 0x71, 0x25, 0x99, 0x0c, 0x09, + 0x86, 0x19, 0xd9, 0x2a, 0xa4, 0x60, 0x70, 0x7f, 0xee, 0x02, 0x2b, 0x8b, + 0xa6, 0xa3, 0xa8, 0x87, 0x9f, 0x6d, 0x58, 0x23, 0x11, 0x7e, 0x25, 0x76, + 0x4e, 0xa2, 0x9a, 0xdd, 0xe3, 0xf4, 0x2d, 0x30, 0xc1, 0xc0, 0x3c, 0xce, + 0xe6, 0x1d, 0x60, 0x67, 0x46, 0xc6, 0x6a, 0x44, 0x16, 0x79, 0xf9, 0x5b, + 0xae, 0x02, 0xde, 0xa9, 0x89, 0xc9, 0x1e, 0xf5, 0xba, 0x77, 0xce, 0x39, + 0x92, 0xf8, 0x91, 0x9f, 0x49, 0x09, 0x71, 0xa4, 0xf1, 0xe0, 0x5a, 0x87, + 0xe1, 0x70, 0xcf, 0x1b, 0xc2, 0x53, 0x6f, 0xad, 0x9e, 0xf5, 0x72, 0x0a, + 0x6b, 0xba, 0x71, 0xab, 0xdd, 0x65, 0xd3, 0x3a, 0x0d, 0xf3, 0xc3, 0x59, + 0x64, 0xfa, 0xac, 0xf4, 0x39, 0x2d, 0x34, 0x32, 0x81, 0x96, 0x6c, 0x0b, + 0xc9, 0xfa, 0x7b, 0x87, 0xa1, 0x2a, 0x28, 0xb3, 0xd9, 0x1f, 0x2c, 0x9a, + 0x83, 0x88, 0x98, 0x09, 0x3f, 0xbb, 0xa2, 0x22, 0xdf, 0x46, 0xa7, 0x12, + 0xb4, 0xa0, 0xa1, 0x3e, 0x56, 0xaf, 0x7f, 0xfc, 0xd4, 0xc7, 0x56, 0xa4, + 0x97, 0xf1, 0x3c, 0x59, 0x1e, 0xaf, 0xb1, 0xa9, 0x76, 0xd6, 0xbc, 0x63, + 0x68, 0x22, 0x61, 0x6e, 0xd0, 0xd5, 0xd5, 0x95, 0x89, 0xc5, 0x72, 0xf1, + 0x3e, 0xf3, 0x33, 0xaf, 0x6b, 0x70, 0x6d, 0xad, 0x43, 0x48, 0xa6, 0x99, + 0xcd, 0x4c, 0xab, 0xcb, 0x31, 0x22, 0x0b, 0x2d, 0xed, 0x2d, 0x4b, 0x51, + 0x83, 0x8b, 0x89, 0x3a, 0x9c, 0x2c, 0xeb, 0xc7, 0x12, 0x85, 0x4d, 0xe8, + 0xf4, 0x84, 0x58, 0x29, 0xa2, 0x4b, 0xcf, 0x66, 0x4c, 0xbc, 0x38, 0xb1, + 0x60, 0x08, 0x7d, 0x97, 0x68, 0x2c, 0x2d, 0x78, 0x32, 0x7a, 0x99, 0xac, + 0x41, 0xa4, 0x62, 0x11, 0x99, 0x29, 0x76, 0x82, 0x63, 0xd4, 0xd0, 0x4c, + 0x25, 0xa1, 0xaa, 0x3e, 0x99, 0x28, 0xaa, 0x6f, 0xd1, 0x78, 0xf9, 0x41, + 0xe8, 0x3f, 0xfe, 0x34, 0x1d, 0x65, 0xc0, 0xf5, 0x73, 0x25, 0xc1, 0x93, + 0x9c, 0xfb, 0x31, 0x58, 0xb0, 0x2f, 0x3c, 0x6b, 0x64, 0x84, 0x4f, 0x9b, + 0xc7, 0xc8, 0x3c, 0xa7, 0x0a, 0xbf, 0x52, 0x5d, 0x20, 0xeb, 0x3b, 0x1d, + 0x0e, 0x81, 0x68, 0xc4, 0x64, 0x2b, 0x3a, 0x3a, 0xba, 0x7f, 0xd7, 0xdb, + 0x93, 0x74, 0x89, 0x57, 0x73, 0x5b, 0x9b, 0xf1, 0xc3, 0xc5, 0x26, 0xf6, + 0x4e, 0x48, 0xc8, 0x51, 0xfc, 0xce, 0xae, 0x32, 0x24, 0xfb, 0xae, 0xb0, + 0x35, 0x9f, 0x29, 0xdd, 0x1b, 0x7e, 0x9d, 0xc0, 0x2b, 0xea, 0x10, 0xe3, + 0x4a, 0x85, 0xc1, 0xd8, 0x28, 0x69, 0xb2, 0xe4, 0x65, 0x5f, 0x15, 0x59, + 0x78, 0x6a, 0x27, 0xf2, 0xd0, 0x5f, 0xdd, 0x05, 0xcb, 0x1e, 0xb0, 0x48, + 0x9f, 0xb8, 0x79, 0xff, 0xd0, 0xc9, 0xf7, 0x20, 0xda, 0xff, 0x92, 0x46, + 0xbc, 0xa7, 0x1f, 0x43, 0x41, 0xfe, 0xc0, 0x3b, 0x8b, 0x95, 0x8e, 0x5d, + 0xd2, 0x32, 0x12, 0x60, 0x13, 0x41, 0xc6, 0x86, 0xb6, 0xfc, 0x6d, 0x79, + 0x14, 0xb3, 0xdc, 0x06, 0xfa, 0x66, 0x67, 0x87, 0xcd, 0x7b, 0xe2, 0x9f, + 0x3f, 0x04, 0x14, 0x60, 0x2b, 0x6f, 0xf6, 0x22, 0xf0, 0x3f, 0x4e, 0x29, + 0x81, 0xb7, 0x57, 0x39, 0x1a, 0xb6, 0xb7, 0xb7, 0xf7, 0x2f, 0x30, 0xb6, + 0xb8, 0x12, 0x56, 0xfb, 0x2c, 0x77, 0x20, 0x36, 0x60, 0x44, 0xd8, 0x65, + 0x8f, 0x69, 0xc7, 0xf8, 0x88, 0x93, 0x80, 0x53, 0x31, 0x90, 0x15, 0x26, + 0x6f, 0x75, 0xeb, 0x2b, 0xa7, 0x47, 0xf2, 0xb1, 0xc1, 0xa0, 0x6f, 0xbd, + 0x12, 0x63, 0x34, 0x95, 0xe1, 0xd4, 0x8f, 0x20, 0x1b, 0x14, 0xbe, 0x96, + 0x45, 0x5b, 0xd8, 0xa4, 0x84, 0x75, 0x1d, 0x20, 0xc4, 0xf4, 0x9f, 0xaa, + 0x20, 0xfe, 0x27, 0x64, 0x84, 0x2d, 0xc7, 0x6a, 0x09, 0x73, 0x2d, 0x7c, + 0x2d, 0x3d, 0xb5, 0x0c, 0x71, 0xba, 0xdd, 0x4b, 0xeb, 0x43, 0x0d, 0x61, + 0xd3, 0x83, 0xcf, 0xad, 0x96, 0x23, 0x80, 0x8f, 0x0a, 0x17, 0x0e, 0x82, + 0xb5, 0x70, 0x19, 0x07, 0xc0, 0x7a, 0x03, 0xf0, 0x30, 0xa5, 0x37, 0x6f, + 0x84, 0x20, 0x2e, 0x42, 0xd4, 0xc0, 0xc0, 0xc0, 0x9f, 0x99, 0x3a, 0x8e, + 0x49, 0x24, 0x95, 0x26, 0xde, 0x22, 0xc2, 0xf1, 0xf0, 0x1f, 0xf7, 0xe2, + 0xaf, 0xd5, 0xcf, 0x37, 0xdf, 0x0a, 0xf6, 0x5d, 0x62, 0xed, 0x0c, 0x40, + 0x84, 0x5c, 0x1e, 0x78, 0x69, 0xdc, 0x8f, 0x1f, 0x17, 0x53, 0xb2, 0xf6, + 0x0e, 0x31, 0xf1, 0x61, 0x75, 0x50, 0xe1, 0x5e, 0x45, 0x20, 0x6b, 0x9e, + 0xbb, 0x35, 0x3f, 0x36, 0xd6, 0x38, 0x30, 0xbe, 0xef, 0x68, 0x80, 0xf4, + 0x0f, 0xe5, 0x59, 0x03, 0x49, 0x84, 0xe4, 0x0e, 0x78, 0xfa, 0x27, 0xce, + 0x9b, 0x58, 0xc8, 0x70, 0x8d, 0x85, 0xf4, 0x7a, 0x44, 0xe6, 0x28, 0x9a, + 0x38, 0xc9, 0xda, 0x8c, 0x56, 0xef, 0xae, 0xb0, 0xa7, 0xf1, 0x69, 0x00, + 0xf6, 0x7e, 0x78, 0xdc, 0xcf, 0x31, 0x34, 0x2d, 0xce, 0xa2, 0xbe, 0x86, + 0x41, 0xc2, 0xd9, 0x38, 0x5b, 0x6d, 0x53, 0xc5, 0xbf, 0x1e, 0xa1, 0xc6, + 0x51, 0x3f, 0xc5, 0x67, 0x8c, 0x12, 0xc9, 0xeb, 0xef, 0x34, 0x7e, 0x37, + 0xfc, 0x6f, 0x6c, 0xf7, 0xe1, 0x68, 0x48, 0xd0, 0xfe, 0x55, 0xcf, 0xba, + 0x32, 0xa6, 0x45, 0xe8, 0x4b, 0x77, 0x3c, 0x99, 0x04, 0xcd, 0x6c, 0x12, + 0x9c, 0xff, 0x7f, 0x19, 0x68, 0x97, 0x17, 0xdf, 0x45, 0x2a, 0xe7, 0xc9, + 0xd8, 0xf4, 0x28, 0x51, 0x8f, 0x51, 0xe4, 0x5a, 0x90, 0x51, 0x22, 0x95, + 0x90, 0x27, 0x13, 0x78, 0x3e, 0xaa, 0xcc, 0xf9, 0xb3, 0xa1, 0xf5, 0xca, + 0x0c, 0x2d, 0xcd, 0xd1, 0xe9, 0x0c, 0x96, 0x89, 0x0a, 0xf2, 0x05, 0x69, + 0xc0, 0x2c, 0x81, 0xbf, 0xce, 0xb8, 0xfa, 0xe0, 0x66, 0x0d, 0xc9, 0xef, + 0x6f, 0x85, 0x0e, 0x26, 0x70, 0x8d, 0xd1, 0xd1, 0xc8, 0x31, 0x0b, 0xac, + 0x6c, 0xc5, 0xf2, 0x39, 0xb1, 0x07, 0x07, 0xe6, 0xde, 0x57, 0xc3, 0x54, + 0x35, 0x35, 0x35, 0x93, 0xe6, 0x28, 0x1c, 0x19, 0x31, 0xc4, 0x7e, 0x2f, + 0x1f, 0x7f, 0x7a, 0x53, 0xed, 0xd2, 0xfd, 0x25, 0xee, 0xd9, 0x14, 0x6e, + 0x7e, 0xbb, 0x99, 0x5c, 0x26, 0xf5, 0x1e, 0x5b, 0xcd, 0xe6, 0xad, 0xa3, + 0x17, 0x5b, 0xd2, 0xa6, 0xe6, 0xcf, 0x9f, 0xde, 0x5c, 0xe1, 0xa0, 0xee, + 0x4d, 0x95, 0xce, 0x7d, 0xbb, 0xf7, 0xcc, 0x52, 0x15, 0x39, 0x73, 0x4f, + 0x40, 0x1a, 0xf2, 0x93, 0xa2, 0x82, 0xd2, 0xa3, 0x8b, 0x29, 0x74, 0x41, + 0x29, 0xcb, 0x29, 0xe9, 0xe4, 0x6c, 0x34, 0xe1, 0xc2, 0x0b, 0x2c, 0x6f, + 0x6f, 0x68, 0x3d, 0xa6, 0x6d, 0xce, 0x18, 0x51, 0x76, 0xba, 0x90, 0xe4, + 0x1d, 0x78, 0xe2, 0xa4, 0xd0, 0x3f, 0x56, 0x41, 0x69, 0x6e, 0x8f, 0x2d, + 0x59, 0xcb, 0x1e, 0x3d, 0xe2, 0x41, 0x8e, 0xd5, 0xd5, 0x0e, 0x2e, 0x15, + 0xa9, 0x65, 0x85, 0xc7, 0x07, 0x17, 0x4f, 0x83, 0x53, 0x53, 0x9f, 0xca, + 0xd5, 0x2a, 0x7b, 0x13, 0xa8, 0xe4, 0x6b, 0xdc, 0x2f, 0x8d, 0xb8, 0x78, + 0x78, 0xe6, 0xff, 0xbb, 0x1d, 0xdb, 0xbf, 0x9e, 0xea, 0xf2, 0xf3, 0xcb, + 0xe4, 0xf7, 0xc2, 0x39, 0xef, 0x7c, 0xae, 0x12, 0xf7, 0xaa, 0x5b, 0x57, + 0x78, 0xba, 0x3d, 0xca, 0x02, 0xcb, 0xe8, 0x35, 0xa3, 0xd6, 0x3a, 0x7c, + 0xc7, 0xaf, 0x3c, 0xdf, 0xda, 0x0a, 0x24, 0xf6, 0x7d, 0x80, 0x00, 0x5d, + 0x00, 0xd8, 0x4d, 0xa7, 0x55, 0x0f, 0x1f, 0x86, 0x46, 0x5c, 0xe5, 0x7c, + 0x56, 0x44, 0xa0, 0xd8, 0xfc, 0x7e, 0xc0, 0x5d, 0xb5, 0xee, 0x15, 0xfc, + 0xd2, 0x6b, 0x44, 0x6d, 0xa1, 0x24, 0x5d, 0xf8, 0xb5, 0xce, 0x7d, 0xbe, + 0xd9, 0x51, 0xac, 0x08, 0x4b, 0x07, 0x47, 0x9a, 0x47, 0xd8, 0x0e, 0xf1, + 0x13, 0x32, 0xa4, 0x63, 0x98, 0x9e, 0x99, 0x0e, 0x09, 0xfa, 0x62, 0x43, + 0x82, 0x64, 0xb6, 0xb3, 0x01, 0x38, 0xc4, 0x41, 0x45, 0x65, 0x03, 0x3d, + 0x34, 0x3e, 0x04, 0xc2, 0x2e, 0x96, 0x03, 0xed, 0x1c, 0x5b, 0xa5, 0x24, + 0x8b, 0xb6, 0xed, 0x5b, 0xf5, 0xf7, 0x84, 0x98, 0xd0, 0xf0, 0xca, 0x4a, + 0x7a, 0xb5, 0x6a, 0xbd, 0x98, 0xb9, 0x72, 0x75, 0x32, 0x56, 0x56, 0x4c, + 0x80, 0x87, 0xfb, 0x76, 0x47, 0x53, 0x3e, 0xc8, 0xaa, 0x7f, 0x60, 0xa0, + 0x67, 0x78, 0x18, 0xc1, 0xd4, 0xd4, 0xd4, 0xfd, 0xf1, 0x8a, 0x02, 0x12, + 0x12, 0x92, 0xc9, 0xec, 0x2f, 0x61, 0x03, 0xa8, 0x29, 0x5d, 0x89, 0xa3, + 0xec, 0xc5, 0xc5, 0xad, 0x7c, 0x64, 0xef, 0xc5, 0xeb, 0x0d, 0x36, 0xd9, + 0xef, 0x9a, 0x36, 0x51, 0x6a, 0x1c, 0xa5, 0xbc, 0xae, 0xae, 0x8e, 0x46, + 0x35, 0xd6, 0x10, 0x5c, 0xa1, 0xdd, 0x54, 0x35, 0xd2, 0x82, 0x51, 0x4a, + 0x98, 0x80, 0x5b, 0x01, 0xa3, 0xf0, 0xab, 0xda, 0xce, 0xc4, 0x30, 0x72, + 0x6d, 0x95, 0xa7, 0xbb, 0xaf, 0x81, 0x9b, 0xf0, 0xa4, 0x92, 0x64, 0xe3, + 0x1a, 0x3d, 0x27, 0x33, 0x16, 0xf7, 0xeb, 0xa1, 0xa4, 0xcc, 0xb0, 0xff, + 0xa7, 0x9c, 0xb0, 0x03, 0x2a, 0x84, 0x9f, 0xc3, 0xd8, 0xf6, 0xb6, 0x86, + 0x61, 0x0c, 0x9f, 0xdb, 0xa7, 0x8a, 0x3a, 0x70, 0xdb, 0x57, 0xb2, 0xd8, + 0xe7, 0x53, 0x0c, 0xb8, 0xea, 0xef, 0x2d, 0x42, 0x04, 0x7a, 0x3e, 0x3b, + 0x6c, 0x75, 0x65, 0x00, 0x30, 0x1a, 0x0e, 0x17, 0x50, 0x58, 0xcd, 0x6e, + 0x01, 0xe4, 0x1e, 0xdd, 0xed, 0x9e, 0x42, 0x52, 0xee, 0xcd, 0xeb, 0xa7, + 0x4a, 0xfa, 0x1f, 0x1d, 0x3a, 0x39, 0x64, 0x10, 0x18, 0x11, 0x34, 0x62, + 0x8a, 0xd7, 0x21, 0xf0, 0x5d, 0x2d, 0xc9, 0x53, 0x65, 0x61, 0x79, 0x71, + 0x45, 0x6a, 0xa5, 0xae, 0xb4, 0xb4, 0xd4, 0x45, 0xab, 0x8e, 0xc4, 0xc0, + 0xca, 0x0a, 0x49, 0x5b, 0x5b, 0x1b, 0xa0, 0x57, 0xb1, 0xf2, 0xe3, 0x91, + 0x5d, 0x47, 0x9d, 0x4e, 0xef, 0x96, 0x31, 0x0d, 0x88, 0x08, 0x15, 0x54, + 0x32, 0x01, 0x75, 0x0a, 0x5a, 0x3a, 0x1c, 0xe3, 0xd1, 0x6c, 0xb2, 0x87, + 0xed, 0x8b, 0x10, 0x9e, 0x9c, 0x5f, 0x8c, 0xba, 0xad, 0xc1, 0xd2, 0x29, + 0x96, 0xeb, 0x6e, 0x59, 0x86, 0xe0, 0x1f, 0xfb, 0x38, 0x1b, 0x13, 0x05, + 0xb8, 0x96, 0x6c, 0x82, 0xfc, 0xb4, 0xb8, 0x9c, 0xe7, 0x82, 0x83, 0xc5, + 0x59, 0x70, 0x4c, 0xd4, 0xf5, 0xac, 0x94, 0x71, 0x07, 0x48, 0x6e, 0xea, + 0xa7, 0xce, 0x8d, 0x64, 0x07, 0x71, 0x67, 0x01, 0x9d, 0xbb, 0xc8, 0x9e, + 0x0e, 0xa9, 0x11, 0xdf, 0xf5, 0x4b, 0xf2, 0xf3, 0x95, 0xd3, 0x5b, 0xa2, + 0xe1, 0x51, 0x88, 0x8c, 0x26, 0xd9, 0xbb, 0xfb, 0x0b, 0xb3, 0xde, 0xaf, + 0xf7, 0xd7, 0xab, 0x8b, 0x0e, 0x7b, 0x3b, 0x77, 0xcb, 0x3b, 0xb9, 0xb9, + 0x17, 0x49, 0xff, 0xeb, 0x42, 0xf1, 0x74, 0xbd, 0x0c, 0xb3, 0xb3, 0xc2, + 0xad, 0xd1, 0xa0, 0xd3, 0xe9, 0xb8, 0x86, 0xf7, 0x42, 0xcb, 0xf9, 0x36, + 0x5b, 0xb0, 0x6f, 0xe9, 0x24, 0x2b, 0x7b, 0xa4, 0xd6, 0xc6, 0xc7, 0x2b, + 0xef, 0x15, 0x22, 0x0f, 0xdf, 0x3d, 0x53, 0x22, 0x3f, 0x67, 0x84, 0xee, + 0xad, 0xd5, 0xf6, 0x1b, 0xef, 0x1a, 0x99, 0x94, 0x3e, 0xe7, 0xff, 0xee, + 0x02, 0x00, 0x42, 0x5a, 0xbb, 0x31, 0x4a, 0x2f, 0x29, 0x37, 0x3a, 0x6d, + 0xfe, 0xba, 0xc0, 0x70, 0x07, 0x90, 0xec, 0x11, 0x45, 0xc7, 0x4f, 0x43, + 0x7f, 0x32, 0xb3, 0xea, 0xcd, 0x07, 0x3f, 0xce, 0x4f, 0x6b, 0xe5, 0x98, + 0x6b, 0x19, 0xe0, 0x3c, 0x07, 0x45, 0xb2, 0xc0, 0xb7, 0xd2, 0xc5, 0x2c, + 0xc5, 0x1e, 0xec, 0x88, 0xb3, 0x1b, 0x98, 0x1a, 0x5d, 0xe2, 0x27, 0xf4, + 0x1b, 0x34, 0xe6, 0x83, 0x86, 0xee, 0x31, 0xba, 0x60, 0x65, 0x0d, 0xf0, + 0xb3, 0x9c, 0xa2, 0xe2, 0x18, 0x8f, 0x50, 0xb1, 0x9a, 0xf7, 0xea, 0x70, + 0x0f, 0x0e, 0x92, 0x69, 0xac, 0xa8, 0x24, 0x55, 0x17, 0xa2, 0x5b, 0xfb, + 0xeb, 0x37, 0xc8, 0x8d, 0xdd, 0xb3, 0x60, 0x12, 0x56, 0x41, 0xe5, 0x61, + 0x80, 0x70, 0xac, 0xa2, 0x5a, 0xc5, 0x0a, 0x9b, 0x1c, 0x6d, 0x51, 0x19, + 0x52, 0xa0, 0x5a, 0x74, 0xf2, 0x7e, 0xed, 0xee, 0xaa, 0x46, 0x7b, 0x53, + 0xcd, 0x46, 0x37, 0x73, 0xdd, 0xb6, 0x3e, 0x98, 0x10, 0x24, 0x92, 0x97, + 0x98, 0x6e, 0x9d, 0xca, 0x77, 0x0a, 0xfb, 0xe6, 0xed, 0x31, 0x23, 0x6a, + 0x6a, 0x6a, 0x86, 0x47, 0x44, 0x40, 0xe4, 0x54, 0x67, 0x0d, 0x52, 0x11, + 0xa2, 0x12, 0x0c, 0x42, 0x92, 0xd5, 0x5b, 0xec, 0x42, 0x23, 0xd5, 0xfd, + 0x1a, 0xfc, 0xfc, 0x18, 0x32, 0x10, 0x1e, 0x23, 0x2d, 0x62, 0x18, 0xdf, + 0x2c, 0x85, 0x16, 0x08, 0x34, 0x7e, 0xde, 0x8c, 0xfa, 0xc7, 0x79, 0xc6, + 0xc7, 0xad, 0x47, 0xfc, 0xa4, 0x18, 0x8a, 0x83, 0x1c, 0x21, 0x41, 0x79, + 0x2e, 0xf6, 0x26, 0xb1, 0xe9, 0x51, 0x99, 0x8f, 0x33, 0x0e, 0x94, 0xea, + 0x47, 0x50, 0xde, 0x1a, 0x30, 0x72, 0xc5, 0x9b, 0x03, 0xfb, 0x98, 0x51, + 0xe8, 0x69, 0x5a, 0xaf, 0x31, 0xfb, 0xb0, 0x1a, 0x69, 0x9e, 0x0b, 0xfd, + 0x24, 0xbf, 0x0c, 0x8a, 0xdf, 0x88, 0xfe, 0xe3, 0xb0, 0xc5, 0xe6, 0xc9, + 0x49, 0x1a, 0x00, 0x62, 0x1f, 0xb7, 0xa6, 0x8f, 0x4f, 0xd6, 0x54, 0xf2, + 0x89, 0x36, 0x04, 0xf3, 0x49, 0x7b, 0x47, 0x7c, 0x41, 0x9a, 0xa0, 0x59, + 0xf7, 0xc0, 0x1c, 0x14, 0x21, 0x7b, 0xf0, 0x6a, 0xe8, 0xaf, 0xfc, 0x4d, + 0x45, 0xa3, 0x69, 0x5b, 0xe5, 0x5a, 0x96, 0xc1, 0xce, 0x0e, 0x40, 0xb4, + 0x59, 0x8e, 0x4f, 0x31, 0x65, 0x5d, 0x03, 0x4d, 0x44, 0x45, 0x89, 0x05, + 0xfe, 0x68, 0xd7, 0x63, 0xa5, 0xdc, 0x20, 0x21, 0x35, 0x82, 0xc6, 0xcb, + 0x41, 0x41, 0xdc, 0x51, 0x7d, 0x68, 0x56, 0x0c, 0x4c, 0x6b, 0xbd, 0x5d, + 0xd0, 0xdf, 0xd3, 0x8e, 0xc9, 0x91, 0x01, 0x88, 0x0a, 0x1a, 0x48, 0xe8, + 0x22, 0x16, 0xee, 0xfc, 0x1c, 0xf2, 0xad, 0xde, 0x06, 0x6a, 0x9d, 0x36, + 0x5c, 0xa4, 0xf4, 0x2a, 0xf7, 0xd3, 0x84, 0xf4, 0xf8, 0x98, 0x88, 0xeb, + 0xce, 0x5e, 0xce, 0x51, 0x53, 0x92, 0xff, 0xf4, 0xaf, 0x73, 0xbe, 0x05, + 0xfa, 0x1a, 0xd4, 0x52, 0x43, 0x37, 0xde, 0xaa, 0xb0, 0x1e, 0x80, 0xb0, + 0x7f, 0x73, 0x86, 0xc0, 0x7b, 0x86, 0x81, 0x6f, 0x38, 0xbb, 0xf7, 0xc3, + 0x16, 0x87, 0x77, 0xef, 0x39, 0xbe, 0x62, 0x45, 0x90, 0x41, 0x88, 0x9b, + 0xd4, 0x9e, 0xda, 0xd0, 0x5d, 0x4e, 0xf1, 0x16, 0x7c, 0x9a, 0x6f, 0xd0, + 0x8d, 0xc9, 0xaf, 0xd2, 0xa4, 0xc3, 0x09, 0x7c, 0xf9, 0xb7, 0x71, 0x91, + 0x56, 0x4e, 0xa3, 0xe9, 0x42, 0x21, 0x64, 0x15, 0xf9, 0xb3, 0xbe, 0x65, + 0x16, 0x31, 0x24, 0x24, 0x24, 0x3c, 0x36, 0x56, 0x2d, 0x21, 0xad, 0xf3, + 0x88, 0x9d, 0x18, 0x9b, 0x40, 0xff, 0x58, 0xca, 0x6e, 0x79, 0x70, 0x4c, + 0x34, 0xdc, 0x6d, 0x0d, 0xdf, 0x5f, 0xc8, 0x6f, 0x82, 0x26, 0xc6, 0x5d, + 0xf3, 0x81, 0x8f, 0x81, 0xe7, 0xa1, 0xb5, 0x20, 0xa8, 0x9a, 0x97, 0xe5, + 0xcf, 0x95, 0xfd, 0xd5, 0xb4, 0x4d, 0x66, 0x9b, 0x27, 0x71, 0x88, 0xd8, + 0xd1, 0x6e, 0x60, 0xd4, 0xff, 0xa3, 0xe9, 0xaa, 0xc3, 0xa2, 0x7e, 0xbe, + 0xee, 0x22, 0x21, 0x21, 0xdd, 0x1d, 0x02, 0x22, 0xdd, 0xdd, 0x12, 0xd2, + 0x48, 0x77, 0x77, 0x77, 0x97, 0x94, 0x74, 0x23, 0xdd, 0x20, 0x25, 0x25, + 0xdd, 0xd2, 0xdd, 0xcd, 0x92, 0x8b, 0x34, 0x2c, 0xdd, 0xf5, 0xee, 0x7e, + 0xdf, 0xe7, 0xf7, 0x3c, 0xfc, 0x39, 0xcc, 0xec, 0xdc, 0xb9, 0xf7, 0xdc, + 0x73, 0x26, 0xee, 0x47, 0x12, 0x8b, 0x11, 0x92, 0x2c, 0x7c, 0xbb, 0x9f, + 0x8a, 0xb1, 0xf0, 0x99, 0x7b, 0xa6, 0x33, 0x38, 0xff, 0xa0, 0xa3, 0xe5, + 0x75, 0x22, 0x87, 0x81, 0xdc, 0x31, 0xaa, 0xfd, 0x28, 0xd2, 0x88, 0x6d, + 0x3e, 0xa7, 0xe5, 0x7d, 0xdc, 0x3c, 0xc9, 0xa2, 0xa0, 0xb6, 0xaf, 0x22, + 0x6a, 0x59, 0xe3, 0x7e, 0x29, 0x99, 0x25, 0x46, 0xb7, 0xe2, 0x0f, 0x74, + 0xd3, 0x36, 0x15, 0xb6, 0x50, 0x56, 0x22, 0x59, 0x7e, 0x24, 0xf4, 0xf1, + 0xb4, 0x35, 0xac, 0x3c, 0xd2, 0xa7, 0x1d, 0x3c, 0x62, 0x52, 0x29, 0x61, + 0xf7, 0xce, 0x71, 0xb7, 0xdb, 0x15, 0x0f, 0xce, 0x6a, 0xf8, 0x9e, 0x91, + 0x41, 0xd8, 0xe6, 0x79, 0x66, 0x70, 0x58, 0x0f, 0x41, 0xe4, 0x63, 0x6d, + 0x62, 0x77, 0x48, 0x58, 0xd6, 0x82, 0x93, 0x0f, 0x0f, 0xe6, 0xab, 0x15, + 0x62, 0x63, 0xbc, 0xbd, 0x4f, 0xec, 0x18, 0x59, 0x9d, 0xb5, 0x08, 0xb8, + 0x03, 0x5f, 0x85, 0xc3, 0x6f, 0x8e, 0x91, 0x85, 0xe3, 0x2b, 0x6f, 0x05, + 0x39, 0x04, 0xd0, 0xaf, 0xba, 0xd7, 0xde, 0xd5, 0x15, 0x5f, 0xb8, 0x81, + 0x6d, 0xe9, 0x5b, 0x9a, 0x6a, 0xa5, 0xbf, 0x96, 0xfe, 0xc1, 0x2d, 0xd9, + 0xdd, 0x93, 0x35, 0x9f, 0x77, 0xe9, 0xfc, 0x2c, 0x31, 0xcd, 0xd0, 0x9f, + 0xaf, 0x19, 0x15, 0x8d, 0x29, 0xa9, 0x7d, 0x92, 0x30, 0x46, 0x4e, 0x0e, + 0xdf, 0xef, 0x61, 0x9e, 0x27, 0x4f, 0xb6, 0x82, 0x1f, 0x6d, 0x19, 0xfb, + 0x5d, 0x39, 0x44, 0x51, 0x6b, 0x57, 0x84, 0x75, 0x2c, 0xb0, 0xd6, 0xa6, + 0xf7, 0xe0, 0x9c, 0x6c, 0xa1, 0xed, 0x11, 0x89, 0xeb, 0x4b, 0x81, 0x32, + 0x05, 0x37, 0xb7, 0x86, 0xc2, 0xe2, 0xf8, 0x24, 0x32, 0x7b, 0xab, 0x38, + 0x53, 0x52, 0x4b, 0x17, 0xf4, 0x8d, 0xca, 0xec, 0xdd, 0x90, 0x4d, 0x09, + 0x4b, 0xbb, 0xf2, 0xdf, 0xa1, 0x7b, 0xca, 0xce, 0x5a, 0x97, 0x6d, 0xb3, + 0x06, 0x37, 0x0d, 0x16, 0xf9, 0x4b, 0x0a, 0x6e, 0xb2, 0xe8, 0xa5, 0xe7, + 0x0f, 0x99, 0xff, 0x9a, 0x79, 0x78, 0x9f, 0x57, 0x1b, 0x18, 0x3f, 0x25, + 0xfe, 0x38, 0x90, 0xc4, 0x0c, 0xde, 0xa0, 0xfc, 0x99, 0x4f, 0xe2, 0xe0, + 0x30, 0x16, 0xcb, 0x4b, 0x32, 0x63, 0x1c, 0x3e, 0x92, 0xf5, 0x8e, 0xb5, + 0xe2, 0x31, 0x8a, 0x11, 0x0f, 0xc5, 0xf5, 0x17, 0x5a, 0xdf, 0x5a, 0x79, + 0x1f, 0x67, 0x75, 0x39, 0x13, 0x4e, 0x59, 0xfb, 0x90, 0x24, 0xa8, 0x6d, + 0x3f, 0x46, 0x60, 0x59, 0x7b, 0xa9, 0x9c, 0x17, 0xb5, 0x00, 0x82, 0x03, + 0xcc, 0xdb, 0x10, 0x14, 0xac, 0x60, 0x93, 0xfc, 0x76, 0xb0, 0x38, 0xf3, + 0x3e, 0x30, 0xaf, 0xa5, 0xd8, 0x59, 0xcd, 0x57, 0xbf, 0xae, 0xbe, 0xe9, + 0x6f, 0x2f, 0x61, 0x5f, 0xe3, 0x46, 0xf3, 0xda, 0xc2, 0x0c, 0x59, 0x25, + 0xbe, 0x42, 0x4f, 0xd2, 0xdd, 0x50, 0xef, 0xaf, 0x71, 0xfc, 0xb0, 0xb7, + 0x6a, 0xe9, 0x6d, 0x88, 0xc3, 0x54, 0x81, 0x25, 0xa7, 0x85, 0x4e, 0xfd, + 0xd7, 0x16, 0x06, 0x39, 0x99, 0x38, 0x72, 0xb9, 0x15, 0xaa, 0xb5, 0x87, + 0x3e, 0x89, 0x87, 0x84, 0x13, 0x5c, 0xb3, 0x73, 0x3a, 0xbe, 0xe6, 0xba, + 0x8b, 0xf7, 0x7a, 0x0e, 0xe1, 0x44, 0x8d, 0x0b, 0x9b, 0xef, 0x82, 0xab, + 0x99, 0x6a, 0xfd, 0x4f, 0xdf, 0xc9, 0x13, 0x2f, 0xd4, 0x28, 0xa2, 0xb2, + 0xab, 0x70, 0xfc, 0x59, 0x18, 0xd4, 0xc0, 0x5b, 0x45, 0xfa, 0x7a, 0xba, + 0xd6, 0xd5, 0x20, 0xfc, 0xd0, 0xe9, 0x7b, 0xd7, 0xf0, 0xc7, 0x42, 0x75, + 0x67, 0xc9, 0x30, 0x50, 0x9d, 0xb8, 0xd9, 0xc5, 0x39, 0xc8, 0xd5, 0x55, + 0xf7, 0x44, 0xc8, 0x4b, 0x91, 0xe5, 0x11, 0x11, 0xde, 0x8f, 0x31, 0x9d, + 0xaf, 0xa3, 0x97, 0x2b, 0xb6, 0xc9, 0xa8, 0x5e, 0xeb, 0x60, 0x6b, 0x0e, + 0x39, 0xaf, 0x83, 0x47, 0x8a, 0x09, 0xcd, 0x74, 0xff, 0x55, 0x35, 0x5f, + 0x66, 0x6c, 0x11, 0x21, 0x2c, 0xad, 0x1d, 0x7b, 0x5c, 0x21, 0x76, 0xec, + 0x6b, 0x7f, 0x95, 0xe7, 0xd9, 0x2d, 0x59, 0x09, 0xd4, 0x37, 0x43, 0x08, + 0xae, 0x35, 0x9d, 0x5a, 0xd7, 0x43, 0x09, 0x09, 0x03, 0xf3, 0x2c, 0xd2, + 0xfd, 0x1a, 0xe3, 0xac, 0xc4, 0x4e, 0x57, 0x8d, 0x86, 0xda, 0xc2, 0xac, + 0xce, 0xd6, 0x2b, 0x2a, 0x34, 0x6d, 0xe1, 0x14, 0xe6, 0x22, 0x02, 0x13, + 0x7f, 0xd1, 0xce, 0x85, 0x13, 0xe3, 0x02, 0x20, 0xab, 0xf9, 0xeb, 0xf1, + 0xea, 0x3b, 0xec, 0x7b, 0x0a, 0xbc, 0xe8, 0xca, 0x0c, 0x05, 0x3a, 0xf4, + 0x3e, 0x56, 0x5e, 0x4f, 0xc5, 0x75, 0x27, 0x01, 0x9e, 0xe6, 0x2f, 0x8a, + 0x01, 0x98, 0x49, 0x73, 0xec, 0x95, 0x5e, 0x72, 0x9e, 0xe9, 0x59, 0x44, + 0xa6, 0x0f, 0xd9, 0x17, 0x56, 0xea, 0x93, 0x4c, 0xd5, 0x28, 0x7a, 0x3a, + 0xcb, 0xc6, 0xe3, 0xf9, 0x64, 0x15, 0xce, 0x6a, 0x27, 0xd0, 0x87, 0x59, + 0x33, 0x0f, 0x5d, 0x70, 0xa7, 0x3d, 0xbb, 0x4e, 0x10, 0x95, 0xea, 0x63, + 0x6e, 0x1d, 0x46, 0x75, 0xa5, 0xaa, 0x3a, 0x87, 0x31, 0x9b, 0x5b, 0x13, + 0x29, 0xf6, 0x81, 0x3f, 0xc8, 0xe3, 0x74, 0xf2, 0x8f, 0xd5, 0xe3, 0x21, + 0x5e, 0x18, 0x55, 0xa7, 0xbf, 0xf6, 0x43, 0xd9, 0x39, 0xc6, 0xf3, 0x7d, + 0x37, 0xba, 0xda, 0xcc, 0xa4, 0xfb, 0xb6, 0xb7, 0x0a, 0x11, 0x28, 0x59, + 0x0e, 0x95, 0x5f, 0xf2, 0xdb, 0x6e, 0x97, 0xba, 0x6d, 0x5c, 0xb7, 0x26, + 0x44, 0x70, 0x33, 0x39, 0xb7, 0xef, 0xfe, 0xfb, 0xb7, 0xd5, 0x1f, 0x89, + 0xad, 0xa3, 0xdd, 0x5c, 0xee, 0xf4, 0x74, 0x6b, 0x4f, 0x4d, 0x93, 0x8a, + 0xb7, 0xe4, 0xe2, 0x6a, 0x13, 0x8e, 0x5e, 0x8a, 0x16, 0x52, 0x5e, 0x07, + 0xf0, 0xcb, 0xf5, 0x58, 0x5f, 0x77, 0x0c, 0xee, 0x33, 0x36, 0xdd, 0x1e, + 0xdf, 0x76, 0xf2, 0x9c, 0xe9, 0x64, 0x0b, 0x54, 0xe8, 0x26, 0x23, 0xdd, + 0xde, 0x53, 0xd3, 0xc1, 0xde, 0x7e, 0x5e, 0x78, 0xba, 0x69, 0xe2, 0x11, + 0x13, 0xf8, 0x00, 0x9e, 0x53, 0xb7, 0x97, 0x9f, 0x7b, 0x10, 0x56, 0xb1, + 0x36, 0xf8, 0x24, 0x54, 0xfe, 0x65, 0x1a, 0xbb, 0x3f, 0x1f, 0xd6, 0xeb, + 0xdc, 0x68, 0x16, 0xab, 0x84, 0xdd, 0xd4, 0x44, 0x7b, 0xe5, 0xaf, 0x81, + 0xd8, 0xbd, 0xd9, 0xa2, 0x56, 0xed, 0xca, 0x6a, 0x6b, 0x14, 0x3b, 0x87, + 0x46, 0x0d, 0xb2, 0xa5, 0xb1, 0xc5, 0x6f, 0x8f, 0x40, 0x6d, 0x7c, 0xba, + 0xa8, 0xde, 0xe2, 0xed, 0x92, 0x66, 0x38, 0x62, 0x6e, 0xbb, 0xb2, 0x3f, + 0x6b, 0x8c, 0x62, 0xa4, 0xe1, 0xc6, 0xb5, 0x6e, 0x87, 0x2a, 0x0b, 0xcb, + 0x11, 0x53, 0x7d, 0x4a, 0x95, 0x7b, 0xbd, 0x25, 0x61, 0x42, 0x90, 0xe8, + 0x5c, 0x3b, 0xaa, 0x3b, 0x90, 0xe5, 0x20, 0x96, 0x63, 0xf4, 0x76, 0xb4, + 0xeb, 0x5c, 0xd2, 0xdd, 0x77, 0x5a, 0x26, 0xe0, 0xaa, 0xbd, 0x4e, 0x79, + 0x3d, 0x7b, 0x20, 0xa6, 0xe6, 0xad, 0xfe, 0x3e, 0xd3, 0xaa, 0x4f, 0x0c, + 0xc1, 0x44, 0x35, 0xa9, 0x5e, 0x51, 0x66, 0xa5, 0xdf, 0x82, 0xf6, 0x21, + 0xd3, 0x56, 0xd6, 0x97, 0x08, 0xfa, 0x74, 0xd7, 0x39, 0x15, 0x6a, 0xbf, + 0xaa, 0xe9, 0x18, 0xea, 0x21, 0x5e, 0x35, 0x7b, 0xb7, 0xf9, 0x2e, 0xba, + 0x44, 0x28, 0x5e, 0xfd, 0xa1, 0x42, 0xdf, 0x82, 0x76, 0xd0, 0xbd, 0x2d, + 0x9e, 0x45, 0x29, 0x5e, 0x31, 0xa0, 0x02, 0xfb, 0x0d, 0x9a, 0x8c, 0xf7, + 0x3e, 0x58, 0x37, 0x6b, 0x63, 0x43, 0x18, 0x5d, 0xa8, 0x6a, 0xa9, 0x62, + 0xf9, 0x20, 0x44, 0xf2, 0x1b, 0xdb, 0xea, 0xaf, 0x56, 0x34, 0xfa, 0xfd, + 0x4d, 0xac, 0x76, 0x72, 0xab, 0xed, 0xd1, 0x24, 0x57, 0x0a, 0x33, 0x24, + 0x5e, 0xf2, 0x59, 0xa9, 0x11, 0xa4, 0x1d, 0x2c, 0xd1, 0x26, 0x86, 0x28, + 0x0e, 0x5e, 0x6c, 0x6f, 0x4d, 0x16, 0x1f, 0x0c, 0xce, 0x90, 0x42, 0x3a, + 0x79, 0xb2, 0x99, 0xe6, 0xec, 0x14, 0x5a, 0x84, 0xce, 0xc8, 0x99, 0x62, + 0xd4, 0x36, 0xd1, 0x69, 0x87, 0x16, 0xad, 0x67, 0x2f, 0x62, 0xd1, 0x4a, + 0xd2, 0x3e, 0xcb, 0x38, 0x62, 0xad, 0xfd, 0xc1, 0xcf, 0xbb, 0x32, 0xf2, + 0x32, 0x9a, 0xc4, 0x59, 0x99, 0x56, 0x3c, 0xcb, 0x91, 0x10, 0xc5, 0x80, + 0xa3, 0x73, 0x64, 0xfc, 0x04, 0x6e, 0x3f, 0x1b, 0xfe, 0xfc, 0x82, 0xba, + 0xd6, 0xea, 0xfa, 0x3e, 0x1a, 0x8f, 0x49, 0x25, 0x39, 0xcc, 0x43, 0xbd, + 0xdd, 0x7d, 0xc6, 0x7b, 0x9b, 0x8c, 0x2c, 0x3e, 0x7a, 0x8b, 0xc2, 0x90, + 0x31, 0x4b, 0x48, 0xd1, 0x12, 0xc6, 0x29, 0xd3, 0x09, 0x4c, 0x8f, 0x54, + 0x6d, 0x67, 0x75, 0x8d, 0x0a, 0x86, 0x5e, 0x88, 0xae, 0x60, 0xeb, 0x8b, + 0x40, 0x40, 0x0a, 0x23, 0x3d, 0xd6, 0x30, 0xcc, 0x9c, 0xce, 0xb7, 0xfa, + 0x83, 0x90, 0x33, 0x66, 0x6f, 0x4a, 0x8f, 0x37, 0xe4, 0x37, 0xc6, 0x7a, + 0x74, 0x48, 0xaa, 0x87, 0x46, 0x0c, 0x49, 0x34, 0x0d, 0x5d, 0x86, 0x0f, + 0xb9, 0x2b, 0xb4, 0xe2, 0xa7, 0x81, 0x5e, 0xd2, 0xd7, 0xe0, 0xdf, 0x8f, + 0x57, 0x75, 0xa6, 0x43, 0xe7, 0x43, 0xe4, 0x81, 0x56, 0xfe, 0xf1, 0x83, + 0xc1, 0x5f, 0xa9, 0x7b, 0x8b, 0x65, 0x92, 0x29, 0x52, 0x7f, 0x6a, 0x1c, + 0xbb, 0xd6, 0xd6, 0xf7, 0xfe, 0x75, 0x61, 0xb2, 0x7f, 0xd0, 0x51, 0x24, + 0xf4, 0x45, 0x8d, 0x1f, 0xeb, 0x29, 0xfb, 0xde, 0xb3, 0xdc, 0xea, 0xb1, + 0xf1, 0xb6, 0xd2, 0x7e, 0x76, 0x4e, 0x37, 0x7a, 0x8a, 0xbe, 0xb5, 0xe9, + 0xd9, 0x54, 0x62, 0xe7, 0x23, 0x4e, 0x51, 0x00, 0xf1, 0x25, 0x4d, 0xeb, + 0xd9, 0x68, 0x3a, 0x64, 0x15, 0xbb, 0x7c, 0xcd, 0x56, 0x7a, 0xe4, 0xa3, + 0x29, 0x97, 0x1b, 0x1f, 0x75, 0x9c, 0xb1, 0x46, 0x3d, 0x16, 0xc9, 0x4e, + 0x6e, 0x1c, 0x78, 0x5c, 0x09, 0xb1, 0x4c, 0x0a, 0xd2, 0xe2, 0xaf, 0xe8, + 0x5c, 0x70, 0x88, 0xd4, 0xa2, 0x5f, 0xcf, 0xb2, 0x26, 0x16, 0x33, 0xee, + 0xee, 0xa4, 0xc7, 0x93, 0x98, 0xbe, 0xa7, 0x4c, 0x4c, 0x5a, 0xdc, 0xf9, + 0xe5, 0x0e, 0xed, 0xaf, 0x78, 0x5b, 0x7a, 0xec, 0x07, 0x51, 0x5a, 0x5a, + 0xee, 0xf9, 0x4f, 0xf5, 0x70, 0xa0, 0x6f, 0xee, 0x36, 0x21, 0x25, 0x81, + 0xff, 0xd8, 0x9f, 0xb1, 0x91, 0xf0, 0xb9, 0xbf, 0xee, 0xbd, 0xc7, 0xaa, + 0x29, 0x50, 0xa6, 0x3b, 0xff, 0x17, 0x83, 0x94, 0x2a, 0xf5, 0x3b, 0xea, + 0xcf, 0x9f, 0x68, 0x0e, 0x73, 0x94, 0x08, 0xaf, 0xec, 0x4d, 0x5a, 0xb7, + 0x6f, 0xe3, 0xaf, 0x88, 0xac, 0x3c, 0xae, 0x24, 0x67, 0x2b, 0xbb, 0x78, + 0xa1, 0x70, 0x4b, 0x55, 0x28, 0x3a, 0xee, 0x2d, 0x47, 0xe6, 0x06, 0x77, + 0x53, 0x76, 0xe1, 0x83, 0x6c, 0x89, 0x4d, 0xa7, 0xa9, 0x0c, 0x9a, 0x6d, + 0x2f, 0x24, 0x5d, 0xa0, 0x3e, 0x74, 0x11, 0x37, 0xfa, 0x9b, 0xc7, 0xf1, + 0x4d, 0x5a, 0x7e, 0xdc, 0xa7, 0x0c, 0x36, 0x6b, 0xea, 0x55, 0xda, 0xfe, + 0xf6, 0x9b, 0xb5, 0x89, 0x1d, 0x93, 0xf3, 0x49, 0x14, 0x74, 0xd3, 0x55, + 0xd2, 0x2f, 0xf9, 0x1e, 0x5f, 0x9c, 0x29, 0x3d, 0xe9, 0xe8, 0x99, 0x1b, + 0x81, 0x4d, 0x51, 0x26, 0x25, 0x2e, 0x85, 0xc5, 0x05, 0x04, 0x42, 0x65, + 0xf8, 0x20, 0x06, 0xfd, 0x12, 0x8e, 0x5f, 0x79, 0xa5, 0x0b, 0xb7, 0x84, + 0x2e, 0x21, 0xcd, 0x18, 0xe4, 0xa0, 0x34, 0x24, 0xfd, 0xa2, 0xc3, 0xc7, + 0x50, 0x6a, 0xdc, 0xd6, 0xe7, 0x3d, 0xfe, 0x1b, 0x8f, 0xa9, 0xe7, 0x93, + 0x25, 0x69, 0x36, 0x82, 0x41, 0x02, 0x84, 0xbb, 0x53, 0x13, 0xa0, 0x41, + 0xbb, 0x07, 0xd3, 0x62, 0x8d, 0xe1, 0xd9, 0xed, 0x15, 0xa7, 0x5b, 0x46, + 0x46, 0x86, 0x56, 0x83, 0x55, 0xe2, 0xfa, 0x72, 0xfe, 0x46, 0x0e, 0x9b, + 0x45, 0xc4, 0x55, 0x0e, 0x61, 0xa3, 0x6c, 0x24, 0x9e, 0x73, 0x6c, 0xf6, + 0xa0, 0xad, 0x2c, 0x06, 0xc1, 0xa3, 0x5b, 0x27, 0xbc, 0xa3, 0xf0, 0x13, + 0xc5, 0xeb, 0xd5, 0xa8, 0x7c, 0xbb, 0xf6, 0xee, 0x06, 0x05, 0xc7, 0x52, + 0xd7, 0x75, 0x33, 0x05, 0xab, 0xdb, 0xf1, 0x96, 0xd6, 0xf7, 0x18, 0x2f, + 0x81, 0x12, 0x95, 0xef, 0x23, 0x3b, 0x08, 0xc0, 0x26, 0xbe, 0x66, 0x44, + 0x1f, 0xff, 0x59, 0x35, 0xc2, 0x2f, 0x54, 0x64, 0xff, 0x7e, 0x4c, 0x68, + 0xeb, 0xf4, 0x9a, 0xb5, 0x9d, 0xa3, 0x07, 0x09, 0x4c, 0x7c, 0x8d, 0xfe, + 0x80, 0x5e, 0x27, 0x17, 0x01, 0x4e, 0xc9, 0x30, 0xdd, 0x7c, 0x6b, 0xeb, + 0xca, 0x9d, 0x88, 0x23, 0x98, 0x86, 0x15, 0x79, 0x6b, 0x22, 0x16, 0x7d, + 0xf8, 0x00, 0x7e, 0xb8, 0xda, 0xdf, 0x99, 0x14, 0x38, 0xfb, 0x9d, 0xe6, + 0xca, 0xa5, 0x36, 0x25, 0x74, 0x97, 0xad, 0x2f, 0x72, 0xb9, 0x95, 0x0f, + 0x78, 0xde, 0x89, 0x2c, 0x57, 0x4c, 0xc6, 0xe1, 0xdb, 0xd7, 0x6a, 0x3f, + 0x05, 0x78, 0x9c, 0x78, 0x06, 0xe4, 0x92, 0x90, 0x10, 0x00, 0xec, 0x9d, + 0x00, 0xb2, 0xb2, 0x63, 0x18, 0x38, 0xf9, 0x62, 0xc9, 0xcb, 0x74, 0xfd, + 0x52, 0x61, 0x7d, 0x76, 0x8d, 0x85, 0xea, 0xf5, 0x83, 0x56, 0x0b, 0xbf, + 0xd9, 0xd4, 0x64, 0xe1, 0x19, 0x35, 0x30, 0xe9, 0x53, 0xb1, 0xd8, 0x12, + 0x8d, 0x23, 0x10, 0xe7, 0x16, 0x9f, 0xf2, 0xaa, 0x9a, 0xd8, 0xff, 0x9c, + 0x46, 0x93, 0x49, 0x86, 0x86, 0x79, 0xf9, 0x8d, 0x90, 0x39, 0xc7, 0xf7, + 0xf8, 0xb7, 0x1b, 0x6d, 0x27, 0x19, 0x32, 0xc4, 0x96, 0xe9, 0x0c, 0xe3, + 0x7d, 0xb8, 0xa0, 0xeb, 0x96, 0x3b, 0xa0, 0x57, 0x57, 0xf6, 0x8d, 0x1e, + 0x48, 0xdf, 0xb2, 0xd9, 0x84, 0xf5, 0x8c, 0x0f, 0xd2, 0x51, 0x17, 0x09, + 0xa4, 0xc1, 0xba, 0x1b, 0x67, 0xcf, 0xef, 0x5a, 0x5f, 0xdd, 0x6e, 0x7a, + 0x5d, 0xaf, 0x7d, 0x12, 0x7d, 0xd0, 0x01, 0xe5, 0x08, 0x78, 0x82, 0x3a, + 0xef, 0x36, 0xfa, 0xc6, 0x58, 0xba, 0x4f, 0x12, 0xaf, 0x7c, 0xdb, 0xfb, + 0x7e, 0xa0, 0x03, 0x85, 0xa2, 0x94, 0xe9, 0xe0, 0x3a, 0x6e, 0xd6, 0xfa, + 0xac, 0xc0, 0x20, 0x7a, 0xbf, 0xe3, 0x0d, 0x89, 0x71, 0xdd, 0x96, 0xf9, + 0x6a, 0x17, 0x1d, 0xe5, 0x7c, 0x84, 0xc0, 0x2c, 0x41, 0xa2, 0x90, 0x47, + 0xb7, 0x60, 0xd9, 0xf2, 0x5a, 0x05, 0x41, 0xb7, 0xfd, 0x28, 0x78, 0xa5, + 0xfa, 0x28, 0xaa, 0xc9, 0xec, 0x6e, 0x3b, 0x1e, 0x8f, 0xa1, 0xf3, 0x57, + 0x07, 0xfd, 0x5d, 0x31, 0xc1, 0x52, 0x85, 0x68, 0xde, 0x06, 0x3b, 0xa2, + 0xe8, 0x86, 0xeb, 0xcb, 0xc8, 0x96, 0x6c, 0x62, 0x29, 0x38, 0xb8, 0xb5, + 0x5f, 0xac, 0x44, 0x9e, 0x73, 0x1c, 0x38, 0xe4, 0xfb, 0x9e, 0xcd, 0x6b, + 0x34, 0x9f, 0x1d, 0x49, 0xb6, 0x7c, 0x6e, 0xef, 0xd2, 0x7b, 0x3a, 0x8f, + 0x0e, 0xb3, 0x49, 0x96, 0xfe, 0x9c, 0xd4, 0x04, 0xf1, 0x37, 0x94, 0xe7, + 0xb1, 0x4c, 0x04, 0xff, 0x3d, 0x07, 0x47, 0xc7, 0x6f, 0xfd, 0x0c, 0x3d, + 0x9e, 0x3a, 0x30, 0xf4, 0xde, 0xc5, 0x25, 0xe1, 0x75, 0xca, 0x37, 0x98, + 0x5c, 0x4a, 0x80, 0x1e, 0xfb, 0x55, 0xb7, 0x83, 0xff, 0x54, 0xd5, 0x59, + 0xc4, 0x6c, 0x2f, 0xac, 0xa0, 0x1b, 0xdd, 0x07, 0x81, 0x15, 0x87, 0xf6, + 0xf0, 0x53, 0xb7, 0x3a, 0xa7, 0x7e, 0x02, 0x1f, 0x23, 0xd2, 0x6a, 0x6e, + 0xc8, 0xbf, 0xb3, 0x6c, 0x78, 0x13, 0xf5, 0x39, 0x9c, 0x22, 0xa7, 0xaa, + 0x18, 0x13, 0x3b, 0x0e, 0x8f, 0x64, 0xbb, 0xc6, 0x39, 0x06, 0xae, 0x84, + 0x77, 0xf4, 0x62, 0x01, 0xb5, 0xa2, 0xef, 0xa5, 0xd2, 0xbd, 0xcf, 0x78, + 0x09, 0x8b, 0xa8, 0xdc, 0xcd, 0x0d, 0xad, 0x06, 0xb1, 0xe8, 0x64, 0x24, + 0x73, 0xb5, 0x03, 0x65, 0xcc, 0x76, 0x3d, 0x91, 0xf4, 0x71, 0xa2, 0x8b, + 0xf4, 0x63, 0x39, 0x10, 0xe0, 0xda, 0x9d, 0xf7, 0x5a, 0x47, 0xec, 0x7a, + 0x16, 0x85, 0xa4, 0x2f, 0xae, 0x06, 0x45, 0xce, 0x0f, 0xe4, 0xc8, 0x8d, + 0xdf, 0x66, 0x8e, 0xb1, 0x6b, 0x09, 0x4c, 0xad, 0x56, 0xfb, 0xcd, 0x09, + 0x1c, 0x30, 0x49, 0xca, 0x7a, 0x18, 0x94, 0xd6, 0x2d, 0xe5, 0x38, 0xb3, + 0x5d, 0xe5, 0xf3, 0x84, 0x49, 0x97, 0xaa, 0x1f, 0x1c, 0x65, 0xa6, 0xea, + 0x2d, 0xa7, 0x4c, 0xae, 0x0f, 0x66, 0x86, 0xc7, 0xc7, 0x1b, 0x62, 0x85, + 0x38, 0xbd, 0x39, 0xc1, 0x64, 0x42, 0xd3, 0x87, 0xcb, 0xcf, 0x85, 0x58, + 0x82, 0x57, 0x7b, 0x96, 0x74, 0x74, 0xb3, 0x30, 0x74, 0x6f, 0x49, 0xd7, + 0xe7, 0xff, 0xbe, 0xa5, 0xb3, 0xfe, 0x11, 0x79, 0x07, 0xeb, 0xb7, 0xcf, + 0xdd, 0x40, 0x27, 0x7b, 0xef, 0xbc, 0xce, 0xfc, 0xdc, 0xf5, 0x14, 0xb1, + 0x7e, 0xdf, 0x6d, 0xb1, 0x79, 0xf6, 0xf3, 0x28, 0x42, 0x42, 0x58, 0xd5, + 0x81, 0x3c, 0x58, 0xd9, 0x7e, 0xe0, 0x9f, 0x01, 0x12, 0x9e, 0xdc, 0xaa, + 0x27, 0x25, 0x25, 0x8b, 0x6a, 0x1f, 0xde, 0x7f, 0xb6, 0xc2, 0x8d, 0xda, + 0x12, 0x2e, 0xb4, 0x72, 0x21, 0x8a, 0x8f, 0xfc, 0xd0, 0xcc, 0x50, 0xfd, + 0x0d, 0x7f, 0x80, 0x5f, 0x28, 0x37, 0xe0, 0x2a, 0x90, 0x37, 0xd1, 0x6d, + 0x66, 0x37, 0xa0, 0x51, 0x56, 0xfb, 0xec, 0x38, 0xab, 0xdd, 0xd3, 0x2e, + 0xd6, 0xf7, 0x8c, 0x24, 0x7c, 0xf7, 0x78, 0xd4, 0x36, 0xa5, 0xb4, 0xb8, + 0x78, 0x2b, 0xd7, 0x17, 0xdc, 0x53, 0xad, 0xdf, 0x8e, 0x81, 0xb1, 0xb5, + 0xc1, 0x75, 0xbb, 0x01, 0x3e, 0x59, 0xa9, 0x27, 0xe0, 0x73, 0xa1, 0xbe, + 0xbc, 0xac, 0xf6, 0x54, 0x68, 0x77, 0x95, 0x08, 0x14, 0x7c, 0x99, 0x5e, + 0x77, 0xea, 0x68, 0xd9, 0xf0, 0x3f, 0xa7, 0xde, 0xd0, 0xab, 0xfd, 0x00, + 0x3f, 0xc0, 0x0f, 0x5c, 0x86, 0xf5, 0x44, 0xed, 0xbb, 0x37, 0xf6, 0x17, + 0xc4, 0x75, 0xe8, 0xac, 0xd7, 0xfa, 0xad, 0x75, 0x39, 0xa6, 0x91, 0x2d, + 0xaf, 0x28, 0xf9, 0xb3, 0xcf, 0xac, 0x65, 0xcf, 0x39, 0x76, 0xba, 0xd2, + 0x55, 0x37, 0x83, 0xea, 0x23, 0x18, 0x0b, 0x8b, 0x24, 0x22, 0x60, 0x1d, + 0x68, 0x7a, 0xbc, 0x61, 0x0a, 0x00, 0x4c, 0x46, 0x3f, 0x65, 0xc8, 0x8b, + 0x8c, 0x23, 0xd4, 0x2a, 0x6f, 0x0c, 0x7f, 0xf5, 0xbf, 0xac, 0x64, 0xb8, + 0x0e, 0x0a, 0x0a, 0xb0, 0xf9, 0x36, 0xdf, 0x9a, 0x3d, 0x18, 0xb0, 0x19, + 0x6a, 0xac, 0xfc, 0xf9, 0xf8, 0xf6, 0x45, 0x0a, 0x44, 0xa2, 0x7b, 0x4b, + 0x32, 0xe0, 0xaf, 0xd4, 0xad, 0x6b, 0xce, 0xfe, 0x3e, 0xa8, 0xec, 0x5c, + 0x99, 0x2e, 0xf5, 0xe6, 0xcd, 0xdc, 0xfb, 0xb1, 0x1f, 0xd3, 0x63, 0xac, + 0x16, 0x8d, 0x4c, 0x30, 0x62, 0xa6, 0x48, 0xba, 0xa8, 0xac, 0xac, 0x6c, + 0x63, 0xea, 0x94, 0x29, 0x29, 0x39, 0x99, 0xcd, 0xe5, 0xdf, 0xd7, 0xf6, + 0xc5, 0x32, 0x26, 0x10, 0xf1, 0x76, 0x9e, 0xd2, 0xc6, 0xfe, 0x75, 0x8c, + 0xd7, 0x50, 0xde, 0xa7, 0xf3, 0x35, 0xdd, 0x3c, 0x20, 0xcd, 0x55, 0xf5, + 0x29, 0xb6, 0xd3, 0x90, 0xd3, 0x53, 0xe3, 0x21, 0x6a, 0xce, 0x0c, 0x64, + 0x95, 0x3a, 0x23, 0x15, 0x47, 0x04, 0x05, 0x39, 0x09, 0xde, 0x5e, 0x87, + 0x8a, 0x1c, 0x18, 0x3c, 0xe5, 0xff, 0xb9, 0xeb, 0xbe, 0x39, 0x78, 0x00, + 0xf1, 0xe4, 0x5e, 0x51, 0x44, 0xe5, 0xba, 0xdb, 0x23, 0xae, 0x3e, 0x05, + 0xa4, 0x4e, 0x4b, 0xd6, 0x15, 0xf3, 0x19, 0x39, 0x7b, 0x5b, 0xaf, 0xd5, + 0xc7, 0x69, 0xd2, 0x84, 0x0d, 0x94, 0xdc, 0xef, 0x3f, 0x19, 0xee, 0x90, + 0xbf, 0xbd, 0x8e, 0x5a, 0x0f, 0xd6, 0x16, 0x29, 0xf3, 0x70, 0x99, 0xb7, + 0x66, 0xb4, 0x2c, 0xd3, 0x09, 0x5e, 0xfc, 0x25, 0xf5, 0x30, 0xf5, 0xbd, + 0x3d, 0xe9, 0x69, 0x71, 0xde, 0xa9, 0xf5, 0xbe, 0xb2, 0xc8, 0xab, 0xa1, + 0x4e, 0xcb, 0xce, 0x8e, 0xc1, 0xfc, 0x28, 0xb5, 0x4c, 0xe3, 0x0a, 0xc1, + 0x89, 0x3b, 0x83, 0xcc, 0xc3, 0xf9, 0x2c, 0x83, 0x52, 0x96, 0xbe, 0xa7, + 0xbc, 0x9a, 0x5a, 0x86, 0x19, 0x60, 0x9b, 0x24, 0x49, 0x6e, 0x1e, 0xdf, + 0x88, 0x25, 0x56, 0x76, 0x8f, 0xd5, 0xe0, 0x6b, 0x91, 0xcc, 0xfd, 0x7d, + 0xbb, 0xbb, 0xe2, 0xdb, 0xd9, 0x02, 0x3d, 0x0d, 0x5e, 0xd7, 0x2b, 0x35, + 0xff, 0xba, 0x38, 0x76, 0xa1, 0xff, 0xc0, 0x39, 0xcc, 0x3a, 0x26, 0x31, + 0xa9, 0x31, 0x70, 0xaf, 0xe3, 0x77, 0xb9, 0x6c, 0x49, 0x3a, 0xb5, 0xe9, + 0xd7, 0xe2, 0xdc, 0x07, 0x75, 0xf1, 0x66, 0x9d, 0x68, 0xfd, 0x9f, 0x3b, + 0xc8, 0x1f, 0xa6, 0xe7, 0xcb, 0xa7, 0xe5, 0x0c, 0x8c, 0x91, 0x7e, 0x09, + 0xde, 0xe0, 0x71, 0xbf, 0x39, 0xff, 0xdb, 0x7b, 0x0f, 0x7b, 0x30, 0x77, + 0xfa, 0x53, 0x27, 0xaf, 0xf2, 0x17, 0x38, 0x8b, 0x75, 0xad, 0x9c, 0xec, + 0x01, 0xc2, 0x3b, 0x58, 0x3d, 0x4e, 0xb4, 0xc6, 0x73, 0x85, 0x80, 0xd5, + 0x2a, 0x99, 0x2c, 0x7c, 0x5e, 0xe7, 0x14, 0xe1, 0x68, 0xa4, 0x36, 0x69, + 0xe3, 0x30, 0x46, 0x7b, 0x9d, 0xcd, 0xed, 0x76, 0x01, 0x97, 0x57, 0x83, + 0x42, 0xc3, 0xd5, 0x6e, 0x03, 0x15, 0x2a, 0xf4, 0xe7, 0xcf, 0x45, 0xd8, + 0xeb, 0x06, 0xef, 0x96, 0xb1, 0xa9, 0x23, 0x8b, 0x8a, 0x1b, 0xc6, 0x9b, + 0xec, 0x9b, 0xb4, 0xea, 0xec, 0x0d, 0xa9, 0x2c, 0x3a, 0x6f, 0x91, 0x5e, + 0x9f, 0x6e, 0x6a, 0x78, 0x3d, 0xf8, 0x07, 0xc0, 0xf7, 0xe9, 0xc3, 0xac, + 0xe3, 0x81, 0xfe, 0x78, 0x6d, 0x0b, 0x75, 0x92, 0xac, 0x17, 0xcc, 0x62, + 0x30, 0xbb, 0xae, 0xd6, 0x70, 0xdb, 0x8f, 0x35, 0xde, 0x95, 0x5c, 0x53, + 0xde, 0x08, 0x74, 0x17, 0x84, 0x01, 0x1e, 0x4f, 0x03, 0xd3, 0x7d, 0x0b, + 0x56, 0x7a, 0x76, 0x38, 0xef, 0x8e, 0x94, 0x41, 0x57, 0x95, 0xb8, 0xc4, + 0x89, 0x9a, 0xca, 0x7a, 0xa7, 0x3b, 0x84, 0x82, 0x3c, 0x0c, 0xfc, 0xa2, + 0x45, 0xbd, 0xa5, 0x57, 0x7b, 0x5b, 0x2b, 0xde, 0x6f, 0x7d, 0x05, 0xd8, + 0xfb, 0x27, 0xb7, 0x2f, 0x67, 0x81, 0x6f, 0x5f, 0x54, 0x54, 0xb0, 0x34, + 0xaa, 0xf5, 0x22, 0xd3, 0xd3, 0x09, 0xe2, 0x07, 0xd4, 0x36, 0xf1, 0x58, + 0x0c, 0x62, 0xf8, 0x5c, 0xf7, 0xfe, 0x5a, 0x71, 0xae, 0xc6, 0x7a, 0x5a, + 0xe7, 0x05, 0xfd, 0xf8, 0x24, 0xc0, 0x5d, 0x4b, 0xd7, 0xfc, 0x52, 0x63, + 0x19, 0x8b, 0x8b, 0x70, 0x73, 0x18, 0x23, 0x35, 0xb3, 0xcd, 0x1c, 0x9f, + 0x4a, 0xbc, 0xbf, 0xe6, 0xd0, 0x6b, 0x6a, 0x9d, 0x81, 0x59, 0x48, 0xb7, + 0x0d, 0x4a, 0x95, 0xcf, 0xee, 0x74, 0x82, 0x8f, 0x94, 0xc1, 0x77, 0x7e, + 0xd0, 0x41, 0x33, 0x29, 0xea, 0xa3, 0x64, 0x0d, 0x2f, 0xc4, 0x12, 0xfa, + 0x40, 0x5b, 0x3f, 0xb7, 0x6f, 0xc5, 0x69, 0xd3, 0x71, 0xdd, 0xcf, 0xb9, + 0xc6, 0xd6, 0x61, 0xd8, 0xc9, 0xb4, 0x44, 0x7d, 0xd9, 0x56, 0x65, 0xa8, + 0x29, 0xe8, 0xb1, 0x79, 0x7a, 0xff, 0xfc, 0x03, 0x15, 0x00, 0x18, 0xfc, + 0xcd, 0xa1, 0xd3, 0x40, 0x17, 0xc0, 0xc5, 0xc4, 0x14, 0xb3, 0x7a, 0xf8, + 0x40, 0xd1, 0xfd, 0xa8, 0x39, 0x9e, 0x0e, 0xc2, 0xd3, 0xf4, 0xcc, 0x00, + 0x36, 0xfd, 0xf6, 0xb7, 0x9e, 0xba, 0x2a, 0x3f, 0xd4, 0x6a, 0xb4, 0x56, + 0x8a, 0xdd, 0x48, 0xd6, 0x0d, 0xf9, 0x77, 0x86, 0x26, 0xf6, 0x9d, 0xc8, + 0xef, 0x75, 0x92, 0x63, 0xb9, 0xf6, 0x85, 0x62, 0x8f, 0x59, 0xcb, 0xc6, + 0xb3, 0xdd, 0x7d, 0xa9, 0x5a, 0x1f, 0x1a, 0x15, 0x01, 0x0f, 0xbb, 0xf8, + 0x0d, 0xf6, 0xc0, 0xda, 0x4f, 0x5f, 0x08, 0x63, 0xa5, 0x3a, 0xae, 0x67, + 0xe5, 0x14, 0xd5, 0xb7, 0x82, 0x2e, 0x0b, 0xc5, 0xce, 0xba, 0x39, 0xeb, + 0x47, 0xfb, 0xd5, 0xf5, 0x2a, 0x9a, 0x3b, 0x2d, 0x3e, 0xb4, 0xf8, 0x5e, + 0x57, 0xdd, 0xe0, 0x59, 0xda, 0x3b, 0xa1, 0xe9, 0x8d, 0x4d, 0xf6, 0x7d, + 0xef, 0x37, 0xcb, 0xe6, 0x4f, 0x0b, 0xb7, 0xd5, 0x7e, 0x40, 0x44, 0x47, + 0x0a, 0x5e, 0xb1, 0x91, 0xd4, 0x50, 0x2c, 0x58, 0xd7, 0x79, 0x40, 0x5e, + 0xf1, 0xae, 0xde, 0x97, 0xb5, 0x9a, 0xa7, 0x8f, 0x21, 0x9c, 0x25, 0xbe, + 0xdb, 0xe4, 0x5a, 0x2b, 0xd8, 0xa5, 0xbd, 0x90, 0x8c, 0x57, 0x24, 0x8d, + 0x16, 0x89, 0xa7, 0xd9, 0xee, 0x5f, 0x91, 0x4b, 0xa0, 0xf6, 0xf7, 0xd3, + 0xd1, 0x19, 0x12, 0x06, 0xa0, 0x8d, 0x92, 0xe2, 0x3b, 0x8b, 0x74, 0xcb, + 0x1e, 0x64, 0x67, 0xe9, 0xfd, 0x94, 0xe7, 0xd0, 0xfd, 0xdd, 0xf8, 0xd8, + 0x31, 0xb6, 0xf4, 0x87, 0xcd, 0x12, 0xfc, 0x89, 0xab, 0xda, 0xbb, 0xea, + 0x9b, 0xef, 0x6b, 0x8d, 0x3e, 0x06, 0x9c, 0x3c, 0x81, 0x3b, 0x83, 0x3c, + 0x1e, 0xca, 0x6b, 0xfb, 0x3d, 0x3e, 0x41, 0xcc, 0x52, 0xcd, 0xb2, 0x62, + 0xae, 0x60, 0xa4, 0xc3, 0x7a, 0xdb, 0x36, 0x24, 0x7b, 0xf6, 0xff, 0xd6, + 0xae, 0x3f, 0x71, 0x98, 0xe1, 0x82, 0xcb, 0x76, 0xb5, 0x5b, 0x6f, 0xc3, + 0x9d, 0x12, 0xbc, 0xfa, 0x00, 0x89, 0x9e, 0x9c, 0x5b, 0x74, 0xf2, 0x69, + 0xd2, 0x9a, 0xc9, 0x00, 0x40, 0xe2, 0x36, 0x25, 0xf3, 0xa6, 0x23, 0x67, + 0x86, 0xbd, 0xdc, 0x3c, 0x80, 0xa2, 0xfa, 0x1b, 0x0e, 0x88, 0x48, 0xb2, + 0x4d, 0x70, 0x71, 0x2e, 0x86, 0x96, 0xa3, 0x09, 0xac, 0xd0, 0x0f, 0x71, + 0xd8, 0xaf, 0xad, 0xd9, 0xdf, 0x47, 0xbd, 0xdb, 0xcb, 0x8a, 0x1b, 0x8e, + 0x78, 0xda, 0xf2, 0x21, 0xee, 0x33, 0x58, 0xcf, 0xc1, 0x9a, 0xaf, 0x29, + 0x2d, 0x11, 0xda, 0xfa, 0xda, 0x4e, 0xd1, 0x25, 0x5d, 0xa2, 0x62, 0x72, + 0x9d, 0xb0, 0xc1, 0xeb, 0x7c, 0x8b, 0x05, 0x10, 0xc5, 0x70, 0xab, 0x69, + 0xb0, 0x6b, 0xbd, 0x74, 0x10, 0xe3, 0x9d, 0x54, 0x55, 0xd9, 0x48, 0xe5, + 0xe3, 0x07, 0x29, 0x06, 0xfc, 0x9c, 0x46, 0x75, 0x8e, 0x33, 0xc5, 0x34, + 0xd6, 0x49, 0x0b, 0x93, 0xac, 0xd8, 0x29, 0xbd, 0x69, 0xaf, 0xec, 0x40, + 0x6e, 0x4b, 0xfc, 0xeb, 0x63, 0xf0, 0xc7, 0xe3, 0x23, 0x14, 0xca, 0xd8, + 0xbe, 0xf8, 0xec, 0xc4, 0x87, 0x7c, 0xaa, 0x3b, 0x00, 0x72, 0x0d, 0x8f, + 0xb0, 0xc4, 0x6f, 0x1a, 0xb1, 0x1a, 0xdd, 0x9e, 0xac, 0x2c, 0xd7, 0x1a, + 0xc3, 0x76, 0xbd, 0xdc, 0xea, 0xf6, 0x0f, 0xfa, 0x68, 0x56, 0x5d, 0x54, + 0x14, 0xff, 0xfa, 0x05, 0x1a, 0xc0, 0x37, 0xec, 0x3f, 0x5a, 0xa8, 0xd4, + 0x57, 0xbc, 0x24, 0x16, 0x6a, 0xc1, 0xdf, 0x08, 0xd8, 0x76, 0xe4, 0xe9, + 0x28, 0xf1, 0xbb, 0xff, 0xe7, 0x9d, 0x42, 0x58, 0x3d, 0x45, 0xf3, 0xd5, + 0x6a, 0x51, 0xeb, 0xa7, 0x09, 0x5b, 0xb6, 0x2b, 0x0e, 0xce, 0xa1, 0xd3, + 0x3f, 0x35, 0x64, 0x15, 0x66, 0xc3, 0x10, 0x08, 0x44, 0x97, 0xff, 0xe3, + 0x3c, 0xb8, 0x46, 0x68, 0xf6, 0x7b, 0xfd, 0x07, 0xfc, 0x61, 0xe4, 0x57, + 0x82, 0xd7, 0xde, 0x1f, 0xb8, 0xb6, 0x58, 0xc3, 0x20, 0xfc, 0xea, 0x81, + 0x0a, 0x99, 0x22, 0xb5, 0x0c, 0x0f, 0x25, 0xd3, 0xe9, 0xd9, 0x4a, 0xd0, + 0x25, 0x39, 0xa0, 0x2b, 0x55, 0x80, 0x1b, 0x24, 0x1c, 0x90, 0x3c, 0xbd, + 0x70, 0x44, 0xc6, 0x34, 0xb1, 0x87, 0xad, 0x38, 0xd0, 0x90, 0x17, 0xe0, + 0x55, 0xa8, 0x4f, 0x7e, 0x91, 0xd9, 0x92, 0xf0, 0xd3, 0xa0, 0xf2, 0x6e, + 0xc4, 0xdf, 0x1d, 0xa7, 0x02, 0xb5, 0x97, 0xf4, 0xe3, 0x63, 0x91, 0xe7, + 0x92, 0x2e, 0xeb, 0x7e, 0xec, 0xdb, 0xb6, 0xf8, 0xd1, 0x8d, 0xc8, 0xd0, + 0x59, 0xf7, 0x5b, 0x1c, 0xc4, 0xd8, 0xc6, 0x33, 0x85, 0x92, 0xe9, 0xec, + 0xe6, 0x51, 0x4b, 0x1a, 0x62, 0x0c, 0xcc, 0xcc, 0x83, 0x4f, 0x67, 0xdd, + 0xf1, 0x61, 0x28, 0xf8, 0x85, 0xbf, 0x7f, 0x8f, 0x3b, 0xe4, 0xfd, 0x25, + 0xe0, 0x6f, 0xb0, 0xff, 0xde, 0xad, 0x40, 0x18, 0x82, 0x09, 0xdb, 0xb6, + 0x79, 0x3d, 0xb5, 0xc5, 0xfb, 0x56, 0x10, 0xf9, 0x41, 0x73, 0x9f, 0xef, + 0x61, 0x40, 0xab, 0x03, 0xe4, 0x49, 0x4d, 0xab, 0xff, 0xfb, 0xf6, 0x08, + 0x36, 0x55, 0x36, 0x2c, 0xe0, 0xe5, 0xd1, 0x18, 0xd4, 0x1f, 0x79, 0x30, + 0x5f, 0x8e, 0x9d, 0xc9, 0x6d, 0x1f, 0x45, 0x2a, 0xe0, 0xb1, 0x95, 0xaa, + 0x69, 0x20, 0x66, 0x5d, 0xfe, 0xb2, 0xe0, 0x0b, 0xfc, 0x79, 0xe1, 0xf5, + 0x7a, 0x96, 0x7c, 0xfc, 0xd1, 0x6d, 0x16, 0xc0, 0x69, 0x4f, 0x12, 0x7b, + 0xd1, 0xf7, 0xf4, 0x72, 0xe3, 0x95, 0xf0, 0x25, 0x29, 0xca, 0x94, 0x00, + 0xa5, 0x94, 0x06, 0x55, 0x78, 0xd0, 0x11, 0xcb, 0xc7, 0xeb, 0x9e, 0xa9, + 0x6d, 0x6d, 0x6d, 0x8e, 0x6a, 0x3f, 0x69, 0x9d, 0xa8, 0x78, 0x55, 0x31, + 0x7c, 0x27, 0x7b, 0x47, 0x56, 0xca, 0xa1, 0x6a, 0xf3, 0x18, 0x95, 0x68, + 0x48, 0xc2, 0x64, 0xe4, 0xfd, 0x94, 0xe9, 0xcd, 0x9e, 0xbf, 0x56, 0x93, + 0x4f, 0xe5, 0xe9, 0x4a, 0x80, 0x87, 0x07, 0xf7, 0x2f, 0x85, 0xac, 0xf0, + 0xb3, 0xae, 0x27, 0x34, 0xf2, 0xc0, 0x67, 0x36, 0x9d, 0xc6, 0xcb, 0xdc, + 0x6a, 0x5d, 0x1a, 0x1a, 0x9a, 0x7b, 0x50, 0x34, 0xcb, 0x79, 0xde, 0xdb, + 0xf3, 0x7b, 0x3e, 0x3e, 0x3e, 0xc5, 0x27, 0x75, 0x59, 0x9a, 0xd7, 0x97, + 0x78, 0x69, 0x36, 0x97, 0x84, 0xb1, 0x87, 0x78, 0xe6, 0xcf, 0x38, 0xb7, + 0xf1, 0x04, 0x44, 0x92, 0xad, 0xdd, 0xd8, 0x06, 0xea, 0x51, 0xb2, 0xb2, + 0x75, 0x0e, 0x40, 0x31, 0xbb, 0xd7, 0x1d, 0x3a, 0x79, 0x8b, 0x31, 0xd4, + 0xf8, 0xd3, 0xb5, 0x56, 0x0e, 0x70, 0xc7, 0x95, 0x62, 0x0c, 0xa9, 0x00, + 0x9e, 0x45, 0x3d, 0x21, 0x44, 0x8d, 0x49, 0x79, 0xb5, 0xbc, 0xf4, 0x77, + 0x2a, 0xe6, 0xf0, 0x43, 0x0b, 0x21, 0xa4, 0xf3, 0x3a, 0x53, 0x25, 0x25, + 0x25, 0xd9, 0xed, 0x68, 0x72, 0xb8, 0x26, 0xfa, 0x70, 0x55, 0x2a, 0x5e, + 0x49, 0x7e, 0xed, 0xe3, 0xf6, 0x1d, 0x84, 0x3b, 0x11, 0xf1, 0x19, 0x5c, + 0xa4, 0x8b, 0x72, 0x5d, 0x3f, 0x0e, 0xc6, 0x10, 0xae, 0x92, 0x49, 0xb6, + 0x14, 0x30, 0x68, 0xbf, 0x0d, 0xef, 0xe8, 0xc1, 0x6c, 0x3e, 0x8f, 0x85, + 0x6f, 0x5a, 0xc8, 0x5f, 0xca, 0x63, 0x63, 0xfd, 0x75, 0xfa, 0x21, 0x9d, + 0x5f, 0x93, 0x8c, 0x9c, 0xaf, 0xd6, 0xb2, 0x2a, 0x60, 0x84, 0x6d, 0x50, + 0x59, 0xaf, 0x70, 0xa8, 0x8e, 0xe3, 0x33, 0x8f, 0xc8, 0xf2, 0xf7, 0xea, + 0x86, 0x0f, 0x77, 0x31, 0xa4, 0x27, 0xb8, 0x9a, 0xdd, 0x36, 0x8d, 0xc8, + 0xeb, 0xfc, 0x0d, 0xbd, 0xe9, 0x94, 0x9d, 0x89, 0x1e, 0x5c, 0xc4, 0x9a, + 0xec, 0xd5, 0x9f, 0x46, 0x50, 0xf0, 0x99, 0xb7, 0xae, 0xa6, 0x44, 0x7e, + 0xf4, 0x18, 0x89, 0xfe, 0x40, 0x23, 0xcd, 0x5f, 0xb0, 0x31, 0x8f, 0x5e, + 0x31, 0x63, 0xdf, 0xae, 0xac, 0xe9, 0xea, 0xfd, 0x37, 0x92, 0x5c, 0x67, + 0x31, 0x41, 0x74, 0x70, 0xe3, 0xd3, 0xfe, 0x82, 0x1c, 0x16, 0x34, 0x13, + 0xe2, 0xbb, 0x7d, 0x53, 0x4a, 0x2e, 0xf1, 0x96, 0x4b, 0x6a, 0x73, 0xbd, + 0x62, 0x93, 0x8a, 0x2c, 0x62, 0xbf, 0x6c, 0x0e, 0x24, 0x5b, 0xae, 0xfc, + 0x98, 0x39, 0xb4, 0xd4, 0x69, 0x7e, 0x34, 0x41, 0x22, 0x18, 0x80, 0xe6, + 0xc8, 0xa4, 0x13, 0x37, 0xb7, 0x3f, 0x47, 0x11, 0xc5, 0x93, 0xeb, 0x46, + 0x42, 0x42, 0x12, 0x33, 0x57, 0xaa, 0x64, 0xfa, 0x7c, 0x7f, 0x61, 0x35, + 0x53, 0x08, 0x0f, 0x7d, 0xb0, 0x6b, 0x3e, 0xd0, 0x5d, 0x56, 0x46, 0x07, + 0x3d, 0x2e, 0xab, 0xd4, 0xac, 0x69, 0xc2, 0xc5, 0xfc, 0x13, 0x45, 0x85, + 0x46, 0x2a, 0xf2, 0x43, 0x40, 0xfa, 0xfa, 0x2e, 0x93, 0xec, 0xa4, 0xbf, + 0xfe, 0x1d, 0x2c, 0x27, 0x84, 0xa8, 0x56, 0x5d, 0x0b, 0x44, 0x73, 0x88, + 0x1a, 0x7d, 0xff, 0xfe, 0x22, 0x32, 0x7f, 0xfc, 0x96, 0xc0, 0xc5, 0x0d, + 0x22, 0x43, 0xb5, 0xbd, 0x55, 0x5d, 0xcf, 0x71, 0x22, 0x49, 0x28, 0x5e, + 0xad, 0xd9, 0xf0, 0xda, 0x02, 0x63, 0x42, 0xdc, 0xb9, 0x78, 0xf0, 0x4c, + 0xc0, 0xf3, 0x33, 0x69, 0x46, 0x2b, 0x3c, 0x8f, 0xc8, 0x74, 0x88, 0x49, + 0xd1, 0xc7, 0xf3, 0x8b, 0x2c, 0xa5, 0xed, 0x1c, 0xfc, 0xd7, 0xf0, 0xfb, + 0xc1, 0xa5, 0xe3, 0xf1, 0xac, 0x09, 0x8b, 0xe7, 0xa7, 0xcd, 0x37, 0xa9, + 0xb9, 0x5f, 0x0a, 0x6c, 0x10, 0xe8, 0x3f, 0xd9, 0xe8, 0x6c, 0x57, 0x0c, + 0xb4, 0x5c, 0xe8, 0xe1, 0xfb, 0x41, 0x17, 0xb5, 0xeb, 0x29, 0x56, 0xad, + 0xd7, 0x33, 0xa7, 0x24, 0x12, 0xbb, 0xbc, 0xac, 0x25, 0xf8, 0xf0, 0x2f, + 0x79, 0x78, 0x72, 0xb2, 0x49, 0x40, 0x83, 0x12, 0xb1, 0xc5, 0x76, 0x1e, + 0xf0, 0x7c, 0x3b, 0x21, 0xe0, 0xf5, 0xb6, 0x9b, 0x71, 0xb0, 0x56, 0x6d, + 0x1e, 0x3b, 0xb5, 0xcf, 0x5b, 0x5e, 0xe7, 0x52, 0xd2, 0xf2, 0xe8, 0x72, + 0x21, 0x8b, 0xb7, 0x17, 0xf8, 0xc2, 0x70, 0x8d, 0x50, 0x34, 0xd7, 0x05, + 0x99, 0x44, 0x69, 0x64, 0x24, 0x7d, 0x2a, 0x32, 0x25, 0xe5, 0x42, 0xa0, + 0xda, 0x5c, 0xb1, 0x0c, 0xb6, 0xdd, 0x46, 0x07, 0xa1, 0x42, 0xa6, 0xde, + 0xdb, 0x43, 0x87, 0x1f, 0x13, 0x71, 0x74, 0x97, 0xae, 0xea, 0x53, 0xbe, + 0x4c, 0x08, 0x8f, 0x8b, 0xb2, 0x52, 0xff, 0x80, 0xd4, 0x4a, 0x13, 0x1f, + 0x4b, 0xf4, 0xe4, 0xd8, 0x93, 0x99, 0xe9, 0xd5, 0x1e, 0xf9, 0x08, 0x4f, + 0xdd, 0x8f, 0x96, 0x58, 0x43, 0x1a, 0xb7, 0x41, 0x4e, 0x4b, 0xd2, 0xa1, + 0x24, 0x16, 0xfd, 0xaa, 0x9b, 0x7d, 0xc9, 0x50, 0xeb, 0xba, 0x83, 0xd8, + 0x4f, 0xb6, 0x5c, 0x23, 0x0a, 0x6d, 0x23, 0xb8, 0x19, 0x24, 0x04, 0xa6, + 0x04, 0x22, 0x1d, 0xe4, 0x1a, 0x01, 0x97, 0xf4, 0xe0, 0x6e, 0xdb, 0x16, + 0x7d, 0x6f, 0x9d, 0x49, 0xbe, 0x26, 0xbb, 0x95, 0xe0, 0x82, 0x2f, 0x3f, + 0x0a, 0x9d, 0x77, 0x06, 0xbd, 0xb6, 0xc3, 0xf0, 0x13, 0x92, 0x92, 0x40, + 0x3f, 0x87, 0xde, 0x27, 0x51, 0x17, 0x94, 0x95, 0x21, 0x0a, 0x78, 0x9c, + 0xfc, 0xcd, 0xe6, 0x73, 0x9d, 0x2e, 0x92, 0x46, 0x87, 0x7b, 0xff, 0xfe, + 0x23, 0x1d, 0x1d, 0x22, 0x93, 0x6e, 0x53, 0x3f, 0x44, 0xfb, 0xc4, 0x80, + 0x4c, 0x9e, 0xf6, 0xd7, 0x9c, 0x63, 0x0b, 0x59, 0x7d, 0x9c, 0x58, 0x18, + 0x03, 0xde, 0xf8, 0x3a, 0x2e, 0x4e, 0x3e, 0x70, 0xc6, 0x45, 0x96, 0x81, + 0xe6, 0x1c, 0xc1, 0x7a, 0x15, 0x2f, 0x7a, 0x88, 0x9e, 0x0a, 0xe2, 0x95, + 0x97, 0x7e, 0x69, 0xb3, 0x17, 0xb7, 0x43, 0x22, 0xbd, 0xf4, 0x06, 0x6f, + 0x54, 0x05, 0x6a, 0xf4, 0x17, 0x5b, 0x21, 0xe8, 0xa0, 0x29, 0x91, 0x37, + 0x09, 0x45, 0x45, 0x34, 0x28, 0x91, 0xf0, 0x7f, 0x74, 0x03, 0xbe, 0x16, + 0x16, 0x52, 0xd9, 0x2d, 0xd7, 0x16, 0x48, 0xed, 0x5b, 0x03, 0x9b, 0x98, + 0x7e, 0x32, 0x6a, 0x9b, 0xdc, 0xed, 0x6e, 0xed, 0x6f, 0xbe, 0xfe, 0x85, + 0x00, 0x20, 0x8f, 0x17, 0xfe, 0x85, 0xf9, 0xa9, 0x2e, 0x4f, 0xdf, 0xec, + 0x5b, 0x97, 0xd9, 0x52, 0x9f, 0x28, 0x0e, 0xca, 0x50, 0x49, 0x69, 0xb7, + 0x12, 0xee, 0x3f, 0xbf, 0xa0, 0xe7, 0x3b, 0x3f, 0xa1, 0xaf, 0x18, 0x26, + 0x8e, 0x69, 0xc5, 0x27, 0x9b, 0xf4, 0xf1, 0x37, 0xc7, 0x33, 0x30, 0x86, + 0x1d, 0x57, 0xf2, 0x39, 0xc2, 0x77, 0x40, 0xc3, 0x26, 0xa3, 0x1e, 0x9e, + 0x4a, 0xdb, 0xeb, 0xdc, 0x9b, 0xe8, 0x4d, 0xf1, 0x7a, 0xde, 0x33, 0xe6, + 0xbd, 0x24, 0x1f, 0x2e, 0x94, 0xe8, 0xae, 0x17, 0xdc, 0x76, 0xb4, 0x6c, + 0xb7, 0x8c, 0x16, 0x42, 0x08, 0x53, 0x6c, 0xf8, 0x0c, 0xc9, 0xd1, 0x51, + 0xcc, 0xfa, 0x6d, 0x41, 0xae, 0x71, 0x7f, 0xfe, 0xb0, 0x4b, 0x48, 0x48, + 0x6c, 0x1d, 0x2d, 0x5c, 0xb2, 0xc8, 0xe2, 0x45, 0xc3, 0x13, 0x12, 0x12, + 0x1e, 0x6c, 0x74, 0x0a, 0x10, 0xf1, 0x38, 0xd8, 0xb5, 0x9b, 0x08, 0x7a, + 0x82, 0x49, 0x54, 0x54, 0x54, 0x9c, 0x4e, 0x96, 0xd9, 0xb2, 0x85, 0x7c, + 0x17, 0x3f, 0x1b, 0x0b, 0xa8, 0x7c, 0xc6, 0x25, 0x98, 0x2f, 0xe5, 0x00, + 0x11, 0x4b, 0x17, 0x05, 0xc6, 0xc7, 0xb5, 0x34, 0x5a, 0xbe, 0xa7, 0x5b, + 0x6b, 0xe8, 0x70, 0x38, 0x5d, 0x7c, 0x49, 0x17, 0x08, 0x2c, 0xb7, 0x6f, + 0xf7, 0x4c, 0x6b, 0xf2, 0xf2, 0x5e, 0x54, 0x6b, 0xf6, 0x6b, 0x2a, 0xea, + 0xfb, 0x34, 0x69, 0xfa, 0xca, 0xd3, 0xbd, 0xca, 0x94, 0x4a, 0x22, 0xec, + 0xc7, 0x8b, 0xc7, 0xa4, 0x13, 0x0a, 0x09, 0xc7, 0x15, 0x52, 0x5b, 0x4e, + 0x22, 0xe8, 0xb3, 0xfc, 0xdf, 0xbf, 0x19, 0x01, 0x7f, 0x6b, 0x8d, 0xfb, + 0x6a, 0xfd, 0x9f, 0x6e, 0x89, 0x44, 0x6e, 0xbd, 0x6e, 0x16, 0x34, 0x2f, + 0x20, 0x02, 0x64, 0xb9, 0x09, 0xd8, 0x10, 0xd3, 0x77, 0x19, 0x56, 0x23, + 0x2a, 0x39, 0x60, 0xf6, 0xac, 0xa2, 0x18, 0xc0, 0x36, 0x28, 0x7c, 0xfd, + 0xa7, 0x8a, 0xcb, 0xa9, 0x35, 0xa8, 0x58, 0x2a, 0x76, 0xd0, 0x7d, 0x6c, + 0xe4, 0xa1, 0xd1, 0xc3, 0xd6, 0x2b, 0x52, 0xf3, 0xbc, 0x32, 0x70, 0x06, + 0x59, 0x52, 0xed, 0x0f, 0xf5, 0x6e, 0xbe, 0x8b, 0x88, 0x5b, 0x72, 0x34, + 0xb2, 0x0e, 0xd7, 0xcd, 0xb4, 0x50, 0x91, 0x11, 0xbb, 0xee, 0xc5, 0xca, + 0xdd, 0x71, 0x85, 0xbb, 0x20, 0x2c, 0xc6, 0x34, 0x60, 0xd5, 0x89, 0x96, + 0xd3, 0x36, 0xe6, 0xa1, 0x66, 0xa2, 0xb7, 0xeb, 0xa3, 0xe5, 0xf9, 0xed, + 0x27, 0x91, 0x65, 0xda, 0x39, 0xb5, 0xad, 0xec, 0x1d, 0x08, 0x98, 0x6b, + 0x41, 0xd6, 0x5d, 0x41, 0xe4, 0x38, 0xcd, 0x30, 0xa0, 0xfc, 0xd6, 0x1b, + 0x62, 0x13, 0x1c, 0x5c, 0x34, 0x88, 0x80, 0x4a, 0xd8, 0x12, 0xbd, 0x3e, + 0x5c, 0x44, 0xc3, 0x96, 0x46, 0x97, 0xa8, 0xdc, 0xe3, 0x0a, 0xec, 0xf8, + 0x46, 0xba, 0x5d, 0x70, 0x1b, 0x4d, 0xae, 0x48, 0x5b, 0x2a, 0x5e, 0xca, + 0xd3, 0xd2, 0x19, 0x66, 0x65, 0xa1, 0x08, 0x23, 0xfc, 0xea, 0x90, 0xc3, + 0x94, 0xf1, 0x23, 0x34, 0x74, 0xab, 0xfd, 0xac, 0xab, 0xaf, 0x3f, 0x12, + 0x5b, 0x9f, 0x8c, 0x1c, 0x03, 0x23, 0x08, 0x42, 0x29, 0xb6, 0x0c, 0xdf, + 0x1e, 0xf1, 0x01, 0x46, 0x77, 0xe0, 0x75, 0x08, 0xd3, 0x96, 0xd0, 0xcb, + 0x9e, 0x3b, 0x1a, 0x23, 0xf6, 0xd9, 0x89, 0xe5, 0x49, 0x48, 0x4c, 0xfc, + 0x4e, 0x23, 0xf7, 0x13, 0x00, 0x50, 0x99, 0x65, 0x3f, 0xef, 0x5b, 0x25, + 0x55, 0xd7, 0x98, 0xf8, 0xd8, 0x55, 0xf5, 0x4d, 0x8d, 0x80, 0xac, 0xcd, + 0x92, 0x33, 0x60, 0xb5, 0xb6, 0x72, 0xd6, 0x45, 0xc1, 0x74, 0xe8, 0xf9, + 0xb9, 0x8f, 0x05, 0xd6, 0x4b, 0x77, 0x72, 0xf9, 0xeb, 0xfa, 0xfd, 0x02, + 0xae, 0x4f, 0xb3, 0x03, 0x39, 0xe2, 0x27, 0xa5, 0x49, 0xb9, 0x9d, 0x8e, + 0x79, 0x0d, 0x32, 0xb9, 0x72, 0x35, 0xa3, 0x27, 0x74, 0x72, 0x8a, 0xdf, + 0x71, 0xa8, 0xaa, 0xbc, 0xfb, 0xf7, 0x5b, 0xd1, 0xa9, 0x5a, 0x5d, 0x0e, + 0xfb, 0x0a, 0xf1, 0xb8, 0x70, 0x30, 0xef, 0x97, 0x18, 0x2b, 0x5c, 0x3d, + 0x79, 0x94, 0xd8, 0x09, 0x14, 0xee, 0x03, 0x26, 0x3c, 0x18, 0x1f, 0xbc, + 0x51, 0x46, 0xf5, 0x04, 0xef, 0xaa, 0xa2, 0xcf, 0x95, 0x99, 0xc4, 0x1b, + 0xc4, 0x0e, 0x96, 0x7f, 0xf1, 0xb5, 0x41, 0xb8, 0xf7, 0x36, 0x6c, 0x5b, + 0xd1, 0x37, 0xb5, 0x96, 0x21, 0xda, 0x2d, 0x5c, 0x9c, 0x43, 0xd6, 0xbd, + 0x82, 0xc0, 0x5e, 0x95, 0xc3, 0x8a, 0x87, 0xc4, 0xcf, 0x45, 0xce, 0xed, + 0xc4, 0xba, 0xbf, 0x2c, 0x76, 0xf1, 0xb6, 0x62, 0xe1, 0x45, 0x28, 0x6a, + 0x6a, 0xe1, 0x44, 0x1f, 0x5c, 0x2f, 0x1b, 0x6d, 0x97, 0x4c, 0xb6, 0x44, + 0xf7, 0x03, 0x4e, 0x52, 0xcd, 0xcd, 0xcc, 0x28, 0x28, 0x29, 0x61, 0x20, + 0xa0, 0x0a, 0x89, 0xf6, 0xbe, 0x28, 0x5c, 0x06, 0x1b, 0xf7, 0xd7, 0xd9, + 0x59, 0x95, 0x06, 0x9b, 0x05, 0xe4, 0xd6, 0xd6, 0x5d, 0x06, 0x8e, 0x5e, + 0xf1, 0x90, 0x3a, 0xeb, 0x11, 0x01, 0x44, 0x64, 0x3b, 0xaf, 0xc6, 0xa3, + 0x48, 0xdf, 0x6c, 0xe1, 0xbc, 0xf0, 0xf7, 0x79, 0xfe, 0x35, 0x97, 0x18, + 0xf8, 0xa1, 0xe7, 0xa7, 0x05, 0x05, 0x2f, 0xb4, 0x38, 0xb8, 0xf6, 0xd5, + 0x9b, 0xfb, 0x8a, 0xc5, 0x06, 0xf7, 0x13, 0x8c, 0x9e, 0x80, 0xe1, 0xc9, + 0x8d, 0x51, 0x42, 0xd5, 0x75, 0x64, 0x2d, 0xbb, 0x3b, 0x6e, 0x9a, 0x48, + 0x53, 0x50, 0xfa, 0x77, 0x45, 0x4d, 0x6b, 0xae, 0x01, 0x82, 0x2f, 0x9b, + 0x0e, 0xa7, 0x75, 0x57, 0x53, 0x3b, 0x3c, 0x39, 0x6a, 0x03, 0x04, 0x7d, + 0x9b, 0x67, 0xa4, 0xfb, 0x4d, 0xba, 0x83, 0xb9, 0x90, 0x9c, 0x3f, 0x03, + 0x61, 0xf5, 0xf2, 0xa4, 0x22, 0x70, 0xb1, 0x85, 0xbd, 0xdf, 0x2a, 0x78, + 0x0a, 0x6b, 0xb5, 0x2c, 0x8f, 0x15, 0x7f, 0xa1, 0x22, 0x4b, 0x04, 0x49, + 0xa1, 0xd6, 0xef, 0x0e, 0xca, 0xd5, 0xe8, 0x70, 0xc7, 0x4a, 0x9e, 0x31, + 0x37, 0x53, 0x54, 0x3b, 0x7f, 0x08, 0x47, 0x3d, 0x88, 0x1b, 0x3a, 0x23, + 0x8e, 0x0f, 0x9c, 0xe8, 0x42, 0x47, 0x5f, 0xe3, 0x22, 0x29, 0x42, 0xb8, + 0x91, 0x48, 0xf3, 0x40, 0x9a, 0x46, 0x80, 0xf7, 0x71, 0xe3, 0xf6, 0x37, + 0x0a, 0x42, 0x28, 0xf1, 0x09, 0xa9, 0x4a, 0xc2, 0x03, 0x14, 0xeb, 0x4d, + 0xfe, 0x4d, 0xe8, 0xca, 0x59, 0x57, 0x81, 0xa3, 0xe3, 0x28, 0x05, 0x9c, + 0xbd, 0x3a, 0x96, 0x54, 0x45, 0x28, 0x95, 0x2a, 0xe6, 0xd4, 0x5a, 0x4e, + 0x91, 0xb9, 0x81, 0xd7, 0x1e, 0x68, 0xcf, 0x18, 0xbb, 0xa3, 0xba, 0x5d, + 0x76, 0x91, 0xa1, 0xf7, 0xc7, 0x3a, 0x3a, 0x04, 0x05, 0x2f, 0x87, 0x3f, + 0x22, 0x7e, 0xf8, 0xfd, 0x90, 0x03, 0xdb, 0xa8, 0x13, 0x6b, 0x31, 0x91, + 0x69, 0xbc, 0x50, 0xa1, 0x0e, 0x00, 0x24, 0x8f, 0x04, 0x07, 0x01, 0x50, + 0x6f, 0x84, 0xef, 0x4c, 0x35, 0xbe, 0xf5, 0xc7, 0xdb, 0x7a, 0xa8, 0x91, + 0x99, 0x64, 0x13, 0xeb, 0x6a, 0x57, 0xed, 0xb9, 0xc9, 0xd0, 0x97, 0x1b, + 0x94, 0x7e, 0x06, 0xa9, 0x3f, 0x1f, 0x21, 0x77, 0xea, 0xfd, 0x15, 0x08, + 0xba, 0x48, 0x1d, 0xfd, 0x48, 0xfe, 0x7c, 0x75, 0x46, 0x20, 0xd4, 0x92, + 0xa6, 0x2b, 0xfc, 0x32, 0x1e, 0x36, 0xe6, 0xb5, 0xdb, 0xe7, 0xe8, 0xc4, + 0x27, 0xd4, 0x3e, 0x6a, 0x4a, 0xd5, 0xf7, 0xa5, 0xf6, 0xf4, 0xe9, 0x8e, + 0x58, 0x2f, 0x52, 0x5d, 0xda, 0x27, 0x04, 0x53, 0xb3, 0x7a, 0x97, 0x82, + 0x8e, 0x15, 0xa0, 0x40, 0x2c, 0xfd, 0x05, 0x83, 0x80, 0xdd, 0x15, 0xd9, + 0x49, 0x98, 0x8b, 0x74, 0x9f, 0x39, 0x55, 0x89, 0xb3, 0x52, 0x6b, 0xdf, + 0x50, 0x59, 0x2d, 0xd8, 0xb8, 0xd9, 0x43, 0x3a, 0xed, 0x16, 0xc9, 0xe0, + 0x41, 0x52, 0xca, 0x91, 0x15, 0x94, 0xfb, 0x69, 0x8f, 0xb2, 0x72, 0xf6, + 0x28, 0xa4, 0xe0, 0xa5, 0xdd, 0xe4, 0xf6, 0x43, 0xda, 0x42, 0x70, 0xa5, + 0x24, 0x8e, 0xa4, 0xdd, 0x7a, 0x56, 0xc4, 0xd9, 0xd2, 0x49, 0xd0, 0x8c, + 0xda, 0xab, 0xe4, 0x27, 0x76, 0x76, 0xac, 0x4f, 0x4a, 0xb9, 0x12, 0x7e, + 0x7e, 0x37, 0x69, 0xb2, 0xb9, 0xc2, 0xfe, 0x44, 0xfa, 0x6d, 0x6e, 0x30, + 0x80, 0xf1, 0x1c, 0x01, 0x7c, 0xc7, 0x8e, 0x0b, 0xa9, 0x2a, 0xd3, 0x47, + 0x08, 0x8a, 0xc7, 0x0d, 0x44, 0xe3, 0xc3, 0xd2, 0xe5, 0xcd, 0x3f, 0x1c, + 0xe3, 0x3b, 0xce, 0x3f, 0x8c, 0x31, 0x5a, 0xa7, 0xf3, 0xee, 0x7b, 0xed, + 0x4d, 0x4c, 0x9d, 0x0f, 0x15, 0x24, 0xa3, 0xf9, 0xaa, 0x8d, 0xec, 0x5e, + 0xc5, 0xce, 0xaa, 0x9a, 0x23, 0xc5, 0xcc, 0x67, 0x6e, 0xd2, 0xb8, 0xa5, + 0x56, 0xac, 0x64, 0xe1, 0x8d, 0x2d, 0x2c, 0x31, 0xc4, 0x4f, 0xa4, 0x73, + 0x22, 0x4f, 0x4d, 0x74, 0x0c, 0xd9, 0xef, 0xb3, 0xea, 0x32, 0x2e, 0xbb, + 0x1e, 0x70, 0x5e, 0x23, 0x7c, 0xac, 0x36, 0xdf, 0xdd, 0xfe, 0xc1, 0x25, + 0xa0, 0xac, 0xe3, 0xf1, 0x82, 0xa6, 0x31, 0x35, 0x69, 0x7f, 0x31, 0xf1, + 0x7e, 0xaa, 0xfd, 0xd4, 0xaf, 0x5f, 0x08, 0x8d, 0x3a, 0x77, 0x20, 0xb9, + 0x86, 0xe9, 0x8f, 0x02, 0x1e, 0x16, 0x41, 0x9f, 0xee, 0xd4, 0x54, 0x99, + 0xba, 0xed, 0x7a, 0x3d, 0x7e, 0x0d, 0x28, 0x2b, 0x55, 0x37, 0xc1, 0x87, + 0x6b, 0xcc, 0xe1, 0x19, 0x4a, 0xb0, 0xde, 0x93, 0xfb, 0x29, 0xef, 0x4c, + 0xb5, 0x1f, 0x57, 0xb7, 0xd7, 0x3a, 0xac, 0xf3, 0x87, 0x42, 0xc2, 0xeb, + 0xef, 0x77, 0xd8, 0x83, 0xe5, 0x3a, 0xd3, 0x58, 0x11, 0x58, 0x3a, 0x16, + 0xa2, 0xf9, 0x0a, 0x75, 0x06, 0x5d, 0xf7, 0xce, 0x48, 0x53, 0x04, 0x13, + 0x30, 0xc7, 0x9c, 0xe3, 0x25, 0x33, 0xa8, 0xf2, 0xcf, 0x15, 0xb2, 0xf3, + 0xd4, 0x6f, 0x6f, 0x3a, 0x77, 0x9d, 0x15, 0x4c, 0x27, 0x36, 0xd6, 0x5a, + 0x5b, 0xcf, 0x90, 0x6d, 0xe5, 0x09, 0x22, 0x04, 0x0c, 0x6d, 0xef, 0xcd, + 0x12, 0x95, 0x4e, 0x94, 0xb7, 0x75, 0x67, 0xb3, 0x9d, 0xc9, 0x10, 0x66, + 0xa0, 0xdc, 0xe2, 0x4f, 0x9d, 0x92, 0xde, 0x88, 0xef, 0x42, 0xac, 0xc6, + 0xff, 0xaa, 0xd2, 0x6f, 0xb6, 0x72, 0x0e, 0xe6, 0xaa, 0x72, 0xd6, 0x5f, + 0x53, 0x1a, 0x6c, 0x9b, 0x74, 0x17, 0xfa, 0x7d, 0xaf, 0xcf, 0x66, 0x60, + 0xbe, 0x3c, 0x7a, 0x34, 0xda, 0xcb, 0x65, 0xef, 0x74, 0x4e, 0x69, 0x52, + 0x09, 0xd4, 0x9c, 0x23, 0x9c, 0xb9, 0x34, 0xbd, 0x1d, 0x68, 0x77, 0xb0, + 0xbd, 0xf9, 0x96, 0x9a, 0xa1, 0xa5, 0x4c, 0xa9, 0xd5, 0xc4, 0x7a, 0x6e, + 0xfa, 0xe3, 0x43, 0xf2, 0x12, 0x7f, 0x0e, 0x9a, 0xea, 0x2f, 0x79, 0x67, + 0x1b, 0x54, 0x5d, 0xfd, 0xba, 0xba, 0x3a, 0xaf, 0xa3, 0xf2, 0x52, 0x3b, + 0x20, 0xb1, 0x27, 0x99, 0xb8, 0x31, 0xdb, 0xcb, 0xe4, 0xad, 0x66, 0xdd, + 0x0c, 0x66, 0x3a, 0x9f, 0x7d, 0x76, 0xb4, 0xd0, 0xe0, 0x22, 0xed, 0x5c, + 0xea, 0x92, 0x20, 0x19, 0x46, 0x39, 0x76, 0xb7, 0xdc, 0x41, 0x5d, 0x5d, + 0x25, 0xfa, 0x3b, 0x18, 0x8f, 0x2a, 0xd8, 0x2b, 0x64, 0xb9, 0xf3, 0xa7, + 0xea, 0xbe, 0x1b, 0x8f, 0x49, 0x30, 0xa9, 0x2e, 0xd0, 0xbe, 0x72, 0x81, + 0xbe, 0xa6, 0x0c, 0x4b, 0x3a, 0x7b, 0x9d, 0xc3, 0x21, 0x61, 0xbd, 0xa9, + 0x7a, 0x3e, 0xa8, 0x26, 0x70, 0xd5, 0x65, 0x4e, 0xd6, 0x01, 0x60, 0x54, + 0xa7, 0x55, 0x77, 0xf7, 0x15, 0x4b, 0x58, 0xbb, 0xad, 0x6b, 0x94, 0xc5, + 0x4e, 0xb3, 0x5a, 0xaf, 0x5c, 0x5d, 0x2f, 0x87, 0xdf, 0xbd, 0x37, 0xe5, + 0xb3, 0x2a, 0x00, 0x20, 0x23, 0x23, 0xc3, 0xa5, 0xc3, 0xb5, 0x75, 0xb0, + 0xe1, 0x7b, 0xd6, 0xd8, 0xc9, 0x9d, 0xc1, 0x74, 0xef, 0x3e, 0xd6, 0xa5, + 0x13, 0x88, 0x67, 0x7d, 0x4f, 0xd6, 0xe2, 0xcb, 0xeb, 0x40, 0xbe, 0xb7, + 0x36, 0x25, 0x9e, 0xe4, 0x62, 0xa8, 0x4c, 0x07, 0x7a, 0x3f, 0x86, 0x81, + 0x55, 0x4e, 0xd3, 0x9d, 0x89, 0xf3, 0x1e, 0x40, 0x43, 0x43, 0xee, 0x5a, + 0xc2, 0xce, 0x2d, 0x91, 0xe4, 0x66, 0x4a, 0x1f, 0x5f, 0x6a, 0xb9, 0xbb, + 0x1d, 0xb7, 0xfd, 0xe2, 0xb0, 0x9c, 0x5a, 0xd9, 0xd4, 0xfb, 0xa5, 0xf1, + 0xde, 0xba, 0xcf, 0x01, 0xd8, 0xf4, 0x97, 0x80, 0x2c, 0x57, 0x10, 0x21, + 0x58, 0x54, 0x66, 0x1d, 0xc8, 0x69, 0x8f, 0x15, 0x12, 0x4c, 0x45, 0x3a, + 0x69, 0xd0, 0x62, 0x47, 0x3c, 0x36, 0xce, 0xf4, 0x77, 0x37, 0x86, 0xc4, + 0xcd, 0x6a, 0x8e, 0x44, 0x0c, 0x2d, 0xf9, 0x9f, 0xbc, 0x05, 0xca, 0x2d, + 0xa9, 0x4c, 0x6f, 0x73, 0x65, 0x93, 0xf1, 0x45, 0xd4, 0x66, 0xdd, 0x9b, + 0xd5, 0x2c, 0xea, 0x59, 0x97, 0x5e, 0x97, 0x1f, 0x61, 0xbd, 0xc5, 0x44, + 0x85, 0xba, 0x9d, 0xb3, 0xb3, 0xb3, 0xd6, 0x1f, 0x33, 0x24, 0xde, 0xfd, + 0x16, 0xaf, 0x0b, 0xaa, 0x5f, 0x4a, 0x79, 0x68, 0x8d, 0x6d, 0x7b, 0x63, + 0xe4, 0xc4, 0x3c, 0x0e, 0x31, 0x45, 0xd2, 0xf1, 0xa0, 0xe7, 0x87, 0x2b, + 0x40, 0x90, 0xea, 0xfe, 0x2c, 0xab, 0xf3, 0x89, 0xa8, 0x76, 0x3b, 0x00, + 0xeb, 0x81, 0x0e, 0x0e, 0xa6, 0xef, 0xbd, 0xdb, 0x50, 0xb9, 0x6b, 0x79, + 0x4b, 0xa6, 0x76, 0xab, 0x08, 0xbc, 0x65, 0xcc, 0xe7, 0x47, 0xe7, 0x8d, + 0x7b, 0xd7, 0xfc, 0x61, 0x01, 0x22, 0xe5, 0x04, 0xe2, 0xcb, 0xf6, 0x50, + 0x34, 0x40, 0xf0, 0xf4, 0x67, 0xb9, 0xa4, 0xd9, 0xbc, 0x2a, 0x41, 0x0d, + 0xad, 0xdf, 0x7d, 0x0b, 0xe3, 0x7a, 0xcd, 0x0a, 0x71, 0x95, 0x8c, 0x82, + 0x6a, 0xd1, 0xa7, 0x4f, 0x58, 0xf6, 0x42, 0xcd, 0xea, 0xf4, 0x34, 0xaf, + 0xdc, 0x61, 0x58, 0x6d, 0x3c, 0x10, 0xcf, 0x4a, 0xe8, 0xd2, 0xc7, 0xc0, + 0x26, 0x0c, 0xff, 0xf2, 0x69, 0x72, 0xa5, 0xa2, 0xd5, 0xdc, 0x6c, 0xdf, + 0xf4, 0x0a, 0xfc, 0xf1, 0xab, 0xcc, 0x98, 0xa8, 0x47, 0x00, 0x26, 0x96, + 0x92, 0x61, 0x3f, 0x38, 0xa4, 0xb4, 0xf6, 0xbe, 0x74, 0x62, 0xd9, 0xf5, + 0x9e, 0xd3, 0xe5, 0x32, 0x9a, 0x04, 0xd9, 0x1d, 0xc0, 0x04, 0x32, 0xbd, + 0x88, 0x1f, 0x2a, 0x2d, 0xd4, 0xaf, 0xfc, 0xc5, 0xeb, 0xf2, 0x47, 0xd0, + 0x7b, 0xef, 0xdf, 0x3f, 0xa3, 0xa3, 0xf9, 0xf2, 0x88, 0xc8, 0x72, 0xef, + 0x6f, 0x05, 0x90, 0x48, 0xdf, 0x1e, 0xcf, 0xe0, 0xf8, 0x2a, 0x2b, 0x2b, + 0x0e, 0xa1, 0xab, 0x31, 0x52, 0x1f, 0x07, 0x63, 0x08, 0x5d, 0xaf, 0x78, + 0xf8, 0x8d, 0x62, 0x0a, 0x14, 0xb2, 0xb8, 0x9b, 0x46, 0x9c, 0xf1, 0x2a, + 0x71, 0x29, 0x57, 0x29, 0xae, 0x8b, 0x09, 0xcf, 0x02, 0xa2, 0xd9, 0xc2, + 0x2d, 0x9c, 0xd9, 0x20, 0xba, 0x2d, 0x68, 0x7d, 0x8a, 0x6d, 0x7f, 0x90, + 0x60, 0x90, 0xe0, 0x7d, 0x4c, 0xbb, 0xe3, 0xb9, 0x07, 0x88, 0xe6, 0x19, + 0xfc, 0x53, 0x00, 0x00, 0x87, 0x10, 0xbe, 0x0b, 0x40, 0x2e, 0xbd, 0x51, + 0x07, 0xde, 0x91, 0xf6, 0x95, 0x30, 0x4c, 0x4e, 0x09, 0xad, 0x17, 0x5c, + 0xe2, 0x87, 0x6d, 0xe5, 0x03, 0x64, 0xf7, 0x0c, 0xc0, 0xb9, 0xce, 0x21, + 0x75, 0xce, 0x23, 0x02, 0x04, 0xcb, 0x4f, 0x3e, 0x37, 0xdc, 0xd1, 0xea, + 0xfd, 0x89, 0xaa, 0xf8, 0xb5, 0x7e, 0xeb, 0xcc, 0xcf, 0x6d, 0xe6, 0x22, + 0x1e, 0xe4, 0x82, 0x61, 0x49, 0x2a, 0x4f, 0x8b, 0x55, 0x31, 0x6c, 0x12, + 0x92, 0xa1, 0x26, 0xab, 0xa4, 0x5f, 0x2e, 0xfa, 0x82, 0xd3, 0xd8, 0x02, + 0xbc, 0x44, 0x04, 0xd9, 0xdd, 0x19, 0x21, 0xe8, 0xde, 0x64, 0xea, 0x71, + 0xba, 0xaa, 0x7e, 0xdc, 0x02, 0x7d, 0x9c, 0x03, 0x07, 0x9f, 0x1a, 0xb8, + 0x68, 0x99, 0xe7, 0x1f, 0x0e, 0xa1, 0xbf, 0x8b, 0x47, 0xae, 0x3e, 0x37, + 0x47, 0x61, 0x65, 0x65, 0xc7, 0x5c, 0x9d, 0x9e, 0x27, 0x22, 0x60, 0x2e, + 0x7d, 0x40, 0xa4, 0x60, 0x5b, 0x93, 0x63, 0x18, 0x26, 0xac, 0x2f, 0x7f, + 0xac, 0x6b, 0x75, 0xa0, 0x64, 0x89, 0x0d, 0x8f, 0x68, 0x78, 0xc2, 0x57, + 0xd4, 0x07, 0x73, 0xf1, 0xa5, 0x43, 0xee, 0x34, 0x36, 0x3c, 0xb7, 0x09, + 0x67, 0xbd, 0x24, 0x5e, 0x6e, 0x30, 0xff, 0xc1, 0x11, 0x93, 0x3b, 0xb7, + 0xf5, 0x09, 0x05, 0x1d, 0xee, 0x2e, 0x8f, 0x84, 0xcb, 0x55, 0xb4, 0x9d, + 0xe6, 0x71, 0xbf, 0xaf, 0x64, 0xf8, 0x0f, 0xa3, 0xed, 0xb5, 0x4f, 0x75, + 0x4e, 0x60, 0x55, 0x02, 0xae, 0x96, 0x25, 0x54, 0xb9, 0x12, 0xee, 0x78, + 0xdb, 0x50, 0xf3, 0x2b, 0xc3, 0x5e, 0x70, 0x9e, 0x70, 0xef, 0xcf, 0x92, + 0x33, 0xe8, 0x5e, 0x08, 0xca, 0xa9, 0x61, 0xea, 0x9e, 0x9a, 0x2c, 0x4d, + 0x5b, 0x83, 0x5c, 0x2d, 0xa9, 0xef, 0xc1, 0x74, 0x81, 0xce, 0xd0, 0x7c, + 0x93, 0xbd, 0xae, 0xe0, 0xeb, 0xfd, 0x0e, 0x60, 0x54, 0xae, 0x0f, 0x92, + 0xfe, 0x71, 0x11, 0xbe, 0x4c, 0xd8, 0x06, 0xd1, 0xe1, 0x20, 0x0b, 0x3e, + 0x9d, 0xdc, 0x64, 0xa9, 0xed, 0x33, 0xeb, 0xbb, 0x1f, 0xf7, 0x2b, 0xcf, + 0xb2, 0xde, 0x1c, 0xcc, 0x0f, 0x0e, 0x94, 0x69, 0xdb, 0xd7, 0x15, 0xbf, + 0x16, 0x2b, 0x37, 0x5c, 0x83, 0x75, 0x16, 0xfa, 0x45, 0xb0, 0xf9, 0x01, + 0xac, 0xbf, 0xbc, 0xc7, 0x16, 0xee, 0x2b, 0x14, 0x7c, 0x13, 0xb2, 0x02, + 0x77, 0xda, 0x40, 0x8d, 0x98, 0x84, 0x64, 0xef, 0x62, 0x7f, 0x75, 0xd8, + 0xd3, 0xec, 0x8b, 0x26, 0x2a, 0x06, 0x26, 0x7b, 0x62, 0x38, 0xe6, 0xab, + 0xd1, 0x39, 0xe9, 0x76, 0x33, 0xdf, 0x9f, 0xe7, 0x05, 0x0e, 0x81, 0x71, + 0xc9, 0x8d, 0x67, 0x88, 0x95, 0xb6, 0x9b, 0x02, 0xf4, 0x67, 0x18, 0x99, + 0x11, 0x20, 0xec, 0x6c, 0xba, 0x40, 0xc1, 0x55, 0x50, 0xc4, 0x95, 0x5d, + 0xc3, 0xef, 0x99, 0xc5, 0xcd, 0x3a, 0x2d, 0x48, 0xd9, 0x3e, 0x41, 0x35, + 0xd0, 0x1d, 0x40, 0x30, 0xdb, 0x1c, 0x7d, 0xea, 0x6e, 0x62, 0x62, 0x92, + 0x63, 0x92, 0x29, 0xe8, 0xfd, 0xe7, 0xd4, 0xdd, 0xc2, 0x82, 0x36, 0xe0, + 0xe9, 0xb4, 0x99, 0x98, 0x44, 0xbf, 0x31, 0x83, 0xc3, 0x72, 0xd5, 0x86, + 0x32, 0xa2, 0x30, 0xd4, 0xad, 0x7d, 0xbf, 0xb4, 0x9f, 0x5c, 0x01, 0x92, + 0x7b, 0x9a, 0xd1, 0x8f, 0x8f, 0x4d, 0xe2, 0x5b, 0x3f, 0x2b, 0x3f, 0xb7, + 0x0e, 0xc1, 0x52, 0x71, 0x81, 0xd2, 0xa6, 0xa6, 0x61, 0x44, 0x4b, 0x6c, + 0x3c, 0xc5, 0x31, 0xe6, 0xfd, 0xa9, 0xcb, 0x97, 0xc1, 0x3d, 0x05, 0x33, + 0x66, 0x52, 0xab, 0x8d, 0x76, 0x31, 0xed, 0x55, 0x2c, 0x6b, 0x7c, 0x98, + 0x9d, 0xe3, 0x46, 0xbd, 0xa0, 0x3c, 0xee, 0x95, 0x5c, 0xa5, 0x1b, 0x48, + 0xf2, 0xd5, 0xf0, 0x5f, 0x8e, 0xf4, 0x53, 0xa3, 0xa7, 0xd1, 0xe9, 0x1f, + 0x32, 0x59, 0x9b, 0x16, 0x6e, 0x09, 0xec, 0x75, 0x12, 0x74, 0xba, 0x43, + 0x94, 0x27, 0xe3, 0x21, 0x80, 0x28, 0x86, 0x36, 0xeb, 0xa2, 0x64, 0x88, + 0xe7, 0x68, 0xd5, 0x05, 0xe0, 0xff, 0x2e, 0x8c, 0x58, 0x5b, 0xd3, 0x83, + 0xda, 0x6a, 0xda, 0xc6, 0x56, 0x73, 0x9a, 0x46, 0x58, 0x98, 0x0c, 0x5a, + 0xff, 0x71, 0x38, 0xf1, 0xa3, 0xf3, 0xb3, 0xd7, 0x43, 0xd5, 0x65, 0xb9, + 0xaa, 0xed, 0x86, 0xbc, 0x54, 0xe5, 0x02, 0x68, 0xab, 0x27, 0xe4, 0xab, + 0xcc, 0xe7, 0xb3, 0xf8, 0x2a, 0x8d, 0x4a, 0xd6, 0x5a, 0xcd, 0xd2, 0xac, + 0x8e, 0xe8, 0x7b, 0xf6, 0x41, 0x02, 0x1d, 0x2e, 0xc7, 0xe0, 0x3c, 0x1e, + 0x70, 0xf8, 0x0e, 0x36, 0xc1, 0xa4, 0xc2, 0x29, 0x44, 0x49, 0x4a, 0x4b, + 0xb2, 0x1d, 0x77, 0x08, 0xce, 0x24, 0x66, 0x5d, 0x00, 0x19, 0xdc, 0xea, + 0xf9, 0xbe, 0xfd, 0xd1, 0x0a, 0x15, 0x20, 0x44, 0xf1, 0xd4, 0x79, 0xab, + 0xbf, 0x3b, 0xff, 0xfc, 0x7b, 0xfd, 0xb6, 0x54, 0x77, 0x0a, 0x9f, 0x04, + 0xc7, 0x88, 0xe7, 0x30, 0x62, 0xb1, 0xe0, 0x29, 0xad, 0x36, 0xc1, 0xc8, + 0xad, 0xad, 0x84, 0x26, 0xe8, 0xd2, 0xa3, 0x4e, 0xb7, 0xc9, 0xae, 0xfc, + 0xc6, 0x12, 0x29, 0x38, 0x48, 0x49, 0xe4, 0x05, 0x67, 0x4a, 0xe8, 0x8e, + 0x84, 0xea, 0xe3, 0xc7, 0x3a, 0xeb, 0x39, 0xda, 0x94, 0x9f, 0x8b, 0x0e, + 0x4c, 0x0f, 0xd3, 0x05, 0x5f, 0xec, 0x6b, 0xee, 0xc8, 0x84, 0xf5, 0x8f, + 0xd3, 0x23, 0xce, 0x20, 0x5a, 0x81, 0x60, 0x27, 0xbc, 0xad, 0x4d, 0x76, + 0x7f, 0xdc, 0x84, 0xaf, 0x99, 0x82, 0xb5, 0x36, 0x7e, 0x74, 0x47, 0x2c, + 0xd1, 0xe6, 0x02, 0x18, 0x6a, 0xc0, 0xac, 0x10, 0x15, 0x49, 0xf8, 0x4a, + 0x95, 0x5f, 0xd7, 0xfe, 0x36, 0xc1, 0x77, 0xbe, 0x58, 0x68, 0x0e, 0x25, + 0x27, 0xcd, 0x8a, 0x38, 0x44, 0x42, 0x07, 0x8f, 0xa1, 0xc9, 0x07, 0x11, + 0xca, 0xcd, 0xfe, 0xcc, 0xd6, 0x04, 0xfc, 0x4d, 0xd6, 0x0e, 0xbe, 0xfe, + 0x10, 0xdd, 0xc9, 0xef, 0xaf, 0x11, 0x4f, 0x26, 0x04, 0xbd, 0x98, 0xde, + 0x01, 0x11, 0x81, 0xd3, 0xc7, 0x37, 0x8d, 0x5d, 0xa7, 0x06, 0xad, 0xa0, + 0xec, 0xf6, 0x2c, 0x70, 0x42, 0xf8, 0x71, 0xf9, 0x21, 0x76, 0xfe, 0x37, + 0x81, 0x7d, 0xfb, 0xc9, 0x31, 0x9d, 0x2c, 0x79, 0x6b, 0xf4, 0x51, 0x08, + 0xac, 0x21, 0x88, 0x28, 0x1d, 0x88, 0x2a, 0x4e, 0x1e, 0x71, 0x0e, 0x06, + 0x0b, 0xbb, 0x91, 0xe0, 0x4b, 0x22, 0xbd, 0x3d, 0x5c, 0x5a, 0x76, 0x9c, + 0x83, 0x35, 0xa7, 0xdb, 0x0f, 0xf1, 0xd7, 0x97, 0x0b, 0xfc, 0x31, 0x30, + 0x35, 0x02, 0xb2, 0x6e, 0xc4, 0x33, 0xe7, 0xb2, 0x05, 0x41, 0x3b, 0x3a, + 0x9c, 0xb1, 0x8d, 0x9d, 0x1b, 0x1d, 0xde, 0xf5, 0xba, 0xc2, 0xae, 0x93, + 0xd9, 0x7c, 0x07, 0x0b, 0x95, 0x10, 0x19, 0xff, 0x64, 0xff, 0xb5, 0xb1, + 0xe5, 0x98, 0xc3, 0x08, 0xa0, 0x60, 0x40, 0x3b, 0x09, 0x32, 0x29, 0x72, + 0xda, 0x1f, 0xd6, 0xad, 0x5c, 0xae, 0x0c, 0xe4, 0xa0, 0x36, 0xd3, 0x5a, + 0x5f, 0x55, 0x4d, 0xf2, 0xd9, 0xbe, 0x43, 0x22, 0x05, 0xe0, 0x44, 0x0d, + 0xef, 0xaa, 0xa7, 0x36, 0x6e, 0x76, 0x9d, 0x11, 0x90, 0x3d, 0xed, 0xbf, + 0xd3, 0xeb, 0xd2, 0x70, 0xaf, 0x4f, 0x3d, 0x9a, 0x45, 0x80, 0x2f, 0x94, + 0x2e, 0xbd, 0x04, 0x82, 0xbd, 0xe1, 0x69, 0xdc, 0x5f, 0x05, 0x67, 0x6b, + 0xaf, 0x4f, 0xe6, 0x07, 0xb9, 0x59, 0x76, 0x20, 0x88, 0xd1, 0xe2, 0x76, + 0x38, 0xeb, 0xe0, 0x26, 0x5f, 0xf7, 0xbf, 0xbb, 0x00, 0xb1, 0x9b, 0xca, + 0xa8, 0xb4, 0xc9, 0x48, 0x17, 0x17, 0x17, 0xd0, 0xf7, 0x2b, 0x8b, 0x35, + 0x86, 0x86, 0x3b, 0x77, 0x79, 0x10, 0x36, 0x7d, 0xbb, 0x6a, 0xc4, 0x0e, + 0x5c, 0x5c, 0xc7, 0x66, 0xf7, 0x07, 0x7d, 0x4d, 0xc3, 0x65, 0xa2, 0x29, + 0xff, 0x9d, 0xd1, 0xe3, 0xe4, 0x91, 0xf4, 0x81, 0x32, 0x31, 0x2b, 0x3f, + 0x14, 0xcd, 0x68, 0x30, 0xe6, 0x1f, 0x0a, 0xb2, 0xa4, 0x44, 0x6a, 0x18, + 0xf6, 0x64, 0xb6, 0x52, 0x5f, 0xa7, 0xeb, 0x46, 0x0f, 0xbe, 0xc8, 0x2b, + 0x42, 0xf2, 0xc3, 0xe0, 0xa9, 0x98, 0x23, 0x6d, 0x77, 0xad, 0x1f, 0xc2, + 0x4b, 0x93, 0xff, 0x90, 0x51, 0xb1, 0xb9, 0x78, 0x40, 0x89, 0xfa, 0x15, + 0xed, 0xc1, 0x52, 0x67, 0x88, 0xfd, 0xd3, 0xd5, 0xd4, 0xb1, 0xb0, 0xf5, + 0x3d, 0x24, 0x2f, 0x0c, 0xb4, 0xb9, 0x1f, 0x03, 0x00, 0x35, 0xdd, 0xaf, + 0x8f, 0x0a, 0x71, 0x4d, 0x43, 0x7c, 0x43, 0xc1, 0xf0, 0x28, 0x76, 0x40, + 0x55, 0x07, 0x72, 0x13, 0x5d, 0x1d, 0x99, 0xaf, 0xd1, 0xf7, 0x52, 0x04, + 0x1e, 0xb6, 0x3c, 0x69, 0x4f, 0xbf, 0x17, 0x93, 0x7c, 0xf5, 0xc1, 0x14, + 0x7f, 0x0a, 0x43, 0xd1, 0xb6, 0xb2, 0x1c, 0xd5, 0xf4, 0x8a, 0x5a, 0x5d, + 0x89, 0x4c, 0x8d, 0xd5, 0x35, 0x0e, 0x59, 0x09, 0x26, 0xee, 0x4f, 0x9e, + 0x6e, 0x5a, 0xae, 0x66, 0x96, 0xce, 0xf3, 0x58, 0x02, 0x07, 0x77, 0x6d, + 0xf9, 0x1a, 0xf9, 0x35, 0xad, 0xb5, 0x1f, 0x4e, 0x9f, 0x6c, 0xb5, 0xbd, + 0x97, 0x1f, 0x2c, 0xd7, 0x73, 0x8b, 0x92, 0xc2, 0x2d, 0x95, 0x4b, 0xc4, + 0xb9, 0x0c, 0x03, 0x5f, 0xb8, 0x18, 0x79, 0x0e, 0xc9, 0x03, 0x39, 0x70, + 0x6f, 0xd6, 0x61, 0xb6, 0xe6, 0xcb, 0x55, 0x17, 0x02, 0xb8, 0xa7, 0xf8, + 0x86, 0xd0, 0x45, 0x9e, 0x8d, 0x8e, 0xe3, 0xab, 0x51, 0xd1, 0xfa, 0x7f, + 0xbf, 0x07, 0x97, 0xa9, 0x32, 0xf6, 0xdf, 0x8d, 0x07, 0x1c, 0x38, 0xa4, + 0x8d, 0xb1, 0xc2, 0xec, 0xf0, 0x36, 0xb6, 0xa9, 0x7a, 0xc6, 0xbf, 0x97, + 0x70, 0x88, 0xc0, 0x7a, 0x34, 0x1c, 0x1d, 0xed, 0x1a, 0xdb, 0x13, 0xf4, + 0x6b, 0x51, 0x21, 0xbc, 0x9b, 0x8b, 0x8d, 0x1b, 0x1b, 0x61, 0xe9, 0xbd, + 0xb3, 0x6d, 0xda, 0x01, 0x0f, 0xed, 0x81, 0xb6, 0xf1, 0x85, 0xfb, 0x37, + 0xfa, 0x4a, 0x6d, 0x39, 0x9d, 0xab, 0x5b, 0xfe, 0x3d, 0xda, 0xfd, 0x83, + 0xa8, 0x5f, 0x1b, 0x52, 0x16, 0xeb, 0xf4, 0xcc, 0x21, 0xc3, 0xc0, 0x38, + 0x03, 0x65, 0xe5, 0xa0, 0x1c, 0x01, 0xcf, 0xc5, 0xc3, 0x2b, 0x17, 0xd7, + 0x9a, 0x1a, 0xd2, 0xfd, 0xec, 0x22, 0xcf, 0xb3, 0x0d, 0x68, 0xb5, 0x05, + 0x88, 0xa8, 0x81, 0xcb, 0xa9, 0xee, 0xf0, 0x4a, 0x5c, 0xb0, 0x91, 0x84, + 0xc8, 0xac, 0xc9, 0x1c, 0x81, 0x1f, 0xbb, 0x63, 0x69, 0x3b, 0x13, 0x3c, + 0x9b, 0xfd, 0x10, 0x3e, 0x01, 0x95, 0x5c, 0x4e, 0x93, 0x33, 0x74, 0xf4, + 0x24, 0x67, 0x1d, 0xe7, 0x3c, 0x65, 0xfa, 0xf2, 0xc1, 0x54, 0xaf, 0x55, + 0xea, 0xf5, 0x83, 0x1e, 0xa4, 0x88, 0x35, 0xc9, 0xe9, 0x74, 0x16, 0xc2, + 0xbb, 0x26, 0xef, 0x13, 0x31, 0x17, 0xc8, 0xdd, 0x67, 0x93, 0x3e, 0xa7, + 0xfe, 0x92, 0xae, 0x5a, 0x0c, 0x5e, 0x82, 0x51, 0xad, 0x3f, 0xea, 0xd8, + 0x59, 0xcc, 0x25, 0xbd, 0xd8, 0xea, 0xc7, 0x3c, 0x00, 0x56, 0x91, 0xaa, + 0x8d, 0x56, 0x2c, 0x7d, 0xd4, 0x65, 0xd4, 0xf8, 0xd0, 0x79, 0x06, 0x7f, + 0xf0, 0xd6, 0x26, 0xdb, 0xed, 0xd8, 0xcb, 0x0a, 0xdd, 0x02, 0xbc, 0x0b, + 0x55, 0x20, 0x82, 0x4b, 0x5e, 0x09, 0x96, 0x89, 0xef, 0x8e, 0xb4, 0x5d, + 0xf1, 0x06, 0x04, 0x01, 0x1d, 0xbb, 0x3b, 0x17, 0x39, 0xe6, 0xbf, 0x5f, + 0x4e, 0xda, 0x42, 0x1f, 0x8e, 0x1e, 0x80, 0x56, 0x9a, 0x65, 0x4b, 0xc4, + 0xb3, 0xb8, 0xed, 0xa1, 0xcf, 0x79, 0x20, 0xc4, 0x32, 0xed, 0x8c, 0x7c, + 0xb6, 0x99, 0x61, 0x4f, 0x88, 0x07, 0x76, 0xbb, 0xa0, 0x51, 0x17, 0x5b, + 0xc9, 0x6f, 0x33, 0xb7, 0xaf, 0x94, 0xd5, 0x12, 0x5c, 0xca, 0x7c, 0x6b, + 0x15, 0x23, 0x6b, 0x7e, 0x6c, 0x55, 0xc9, 0x15, 0x59, 0x61, 0xe6, 0x8d, + 0xe4, 0x63, 0xb4, 0x57, 0x8c, 0x98, 0xa4, 0xe6, 0x23, 0x5f, 0xd9, 0x79, + 0x6c, 0x3b, 0xe8, 0x86, 0x27, 0xf3, 0x07, 0x0e, 0xf6, 0x37, 0x1b, 0xc5, + 0xd7, 0xa0, 0x7f, 0x97, 0x71, 0x52, 0x3e, 0x16, 0xcc, 0xdc, 0x60, 0xc1, + 0x50, 0xf2, 0xa5, 0x93, 0xbf, 0xb7, 0xfe, 0x43, 0x4e, 0xec, 0x7c, 0xb8, + 0x32, 0xf8, 0xb3, 0x09, 0xa9, 0xba, 0x11, 0x2d, 0xcb, 0x56, 0xc0, 0xcb, + 0xf8, 0x2b, 0xeb, 0x43, 0xad, 0x2e, 0xf0, 0x23, 0xae, 0x76, 0x19, 0x37, + 0xe2, 0xce, 0x0f, 0x81, 0x66, 0x26, 0xea, 0x2e, 0xb9, 0x72, 0xe5, 0x7c, + 0xfd, 0xe3, 0x5f, 0x5a, 0x77, 0x9a, 0x39, 0x21, 0xd1, 0xf8, 0x2c, 0xa0, + 0xae, 0x27, 0x70, 0x7d, 0x65, 0xa5, 0x01, 0x36, 0x1b, 0x1b, 0xdb, 0xf0, + 0xc8, 0x48, 0xcf, 0x76, 0xdf, 0xe4, 0x69, 0x20, 0x8d, 0x8c, 0xb8, 0x81, + 0x01, 0xd9, 0xe8, 0xe8, 0x68, 0xf6, 0xad, 0xa4, 0x74, 0xb8, 0xf1, 0x86, + 0x2b, 0xba, 0xe9, 0x62, 0x88, 0xa7, 0x4a, 0x1a, 0x97, 0xcb, 0x97, 0x8b, + 0xd8, 0xa2, 0xba, 0xa3, 0xbb, 0x4e, 0x56, 0x02, 0x05, 0x34, 0x5f, 0x89, + 0x12, 0xd9, 0x92, 0x4e, 0xba, 0x28, 0x49, 0x77, 0x06, 0xff, 0xaf, 0x6b, + 0xe1, 0x0e, 0xad, 0x9a, 0x05, 0x0d, 0x6e, 0xee, 0x91, 0x23, 0x29, 0xc2, + 0x69, 0xae, 0x5f, 0xf2, 0xda, 0xc1, 0xf4, 0x88, 0xa8, 0x28, 0x59, 0xc4, + 0xbf, 0x55, 0xd6, 0xd9, 0xc9, 0x10, 0x03, 0xbe, 0x16, 0x44, 0xf8, 0x93, + 0x21, 0x3a, 0x1d, 0x81, 0x0a, 0x79, 0x08, 0x12, 0x53, 0x5c, 0xe0, 0x6d, + 0x9b, 0xc1, 0x43, 0x9a, 0x0c, 0xdc, 0xdb, 0x37, 0x6f, 0x01, 0x3f, 0xca, + 0x95, 0x3a, 0xc3, 0x9e, 0x7b, 0x2f, 0x09, 0x4f, 0x81, 0x77, 0x2b, 0x6f, + 0x6b, 0x79, 0xed, 0x29, 0x60, 0xb5, 0xd8, 0xc8, 0xfb, 0x2e, 0x87, 0x53, + 0xdd, 0x15, 0xda, 0x3c, 0x99, 0xa4, 0x50, 0x5c, 0x06, 0x8d, 0xf9, 0xc3, + 0x2b, 0x04, 0x54, 0x22, 0xb7, 0xab, 0x90, 0xd7, 0x42, 0x8d, 0xcf, 0xce, + 0x77, 0x07, 0xdf, 0xb5, 0x1e, 0x46, 0x2a, 0x09, 0xf8, 0x6a, 0xdf, 0x73, + 0x21, 0x51, 0xf1, 0x94, 0xa8, 0xd1, 0xb1, 0x36, 0x04, 0xa6, 0x26, 0xef, + 0x50, 0x09, 0x91, 0xa0, 0xb5, 0xc2, 0xdc, 0xf1, 0xbc, 0xdd, 0x8a, 0xd9, + 0x2e, 0x85, 0xab, 0xad, 0xa9, 0xac, 0x22, 0x02, 0x0a, 0xcb, 0xa4, 0xfd, + 0x9e, 0xaf, 0x4b, 0xb4, 0xb5, 0x75, 0x2d, 0xa3, 0x4d, 0x7a, 0x28, 0x82, + 0x36, 0x11, 0xb4, 0xf4, 0x5e, 0xf5, 0x2d, 0xf6, 0x70, 0xb6, 0xe6, 0xcc, + 0x8f, 0x2f, 0xae, 0xfb, 0x3c, 0x7b, 0xec, 0x9a, 0x56, 0x4f, 0xc7, 0x58, + 0x18, 0x7b, 0x0e, 0xaf, 0xca, 0x3d, 0x62, 0x05, 0x22, 0xce, 0x54, 0xe9, + 0x71, 0xad, 0xc8, 0x36, 0x11, 0xd3, 0xaa, 0xcd, 0xde, 0x01, 0xf0, 0x18, + 0xb5, 0x82, 0x3e, 0xe5, 0xf9, 0x61, 0xcd, 0xcc, 0xcc, 0x34, 0x3e, 0x76, + 0x40, 0x0b, 0x99, 0xdc, 0x41, 0x72, 0x21, 0x05, 0x33, 0x37, 0xf2, 0x36, + 0xa5, 0xce, 0x87, 0x43, 0x20, 0x7c, 0x1f, 0x82, 0x9b, 0xb4, 0xbc, 0x99, + 0x56, 0xd5, 0xe4, 0x97, 0xe7, 0x25, 0x58, 0x4f, 0xf4, 0xa1, 0xa3, 0xcd, + 0x3b, 0xfe, 0x09, 0xfc, 0x24, 0x6a, 0xc5, 0x4d, 0xc4, 0x4e, 0xc4, 0x97, + 0x29, 0xa7, 0x90, 0xe1, 0xe1, 0x8b, 0x19, 0x49, 0xc9, 0x7d, 0x5d, 0x14, + 0xf1, 0x1e, 0xaf, 0x4a, 0x75, 0x4f, 0x01, 0xa3, 0x43, 0xf8, 0xe5, 0xb7, + 0x2d, 0x8e, 0x41, 0x3d, 0xc5, 0x5c, 0x5d, 0xde, 0x3b, 0x99, 0xb5, 0xc5, + 0xa9, 0x85, 0x62, 0x6c, 0xd0, 0xd8, 0x1e, 0xb3, 0x56, 0x54, 0xa3, 0xee, + 0x2d, 0xb0, 0x29, 0x2f, 0xe0, 0xd1, 0x9a, 0x51, 0xaf, 0xa5, 0x56, 0x2a, + 0x2f, 0x31, 0x3d, 0x3d, 0x02, 0x12, 0xc3, 0x44, 0xd0, 0x18, 0x8b, 0x19, + 0x3c, 0x1e, 0x88, 0x27, 0x30, 0x25, 0x58, 0x6e, 0xc7, 0x96, 0x42, 0x3d, + 0x8a, 0xac, 0x6b, 0xbe, 0x71, 0xd6, 0xbe, 0x88, 0x4e, 0xc8, 0x84, 0xa8, + 0xd9, 0x82, 0x7d, 0x91, 0xfe, 0x11, 0xb3, 0xa1, 0x55, 0xa4, 0x60, 0xc9, + 0xa2, 0xc3, 0xcd, 0x31, 0xb3, 0xd5, 0x40, 0xd9, 0x9f, 0x7f, 0x23, 0x48, + 0x65, 0x0f, 0x1c, 0x16, 0xff, 0x98, 0xb3, 0x8d, 0x4d, 0x92, 0xb1, 0x6e, + 0x58, 0x75, 0x08, 0xe6, 0xba, 0x5e, 0xe5, 0x04, 0x3d, 0x84, 0x93, 0x6a, + 0x75, 0xe5, 0xbd, 0xb1, 0xf3, 0x37, 0xdb, 0x1e, 0x16, 0x1c, 0x44, 0x34, + 0x7f, 0x95, 0x9b, 0x1a, 0xf4, 0x57, 0xea, 0xb6, 0xf5, 0x65, 0x2e, 0xd7, + 0xa8, 0x74, 0xbe, 0x39, 0x52, 0xe7, 0xb4, 0x99, 0x2f, 0x5b, 0xcd, 0x63, + 0xb3, 0x9a, 0xa6, 0x38, 0x01, 0x36, 0x4f, 0x39, 0xc8, 0x13, 0x93, 0x44, + 0x2c, 0xe5, 0x05, 0x60, 0x14, 0xbd, 0xbf, 0x73, 0xb1, 0xed, 0x08, 0xb5, + 0x03, 0xa6, 0x45, 0xe0, 0x6f, 0x3c, 0xf4, 0x5a, 0xeb, 0x15, 0x58, 0xb1, + 0xeb, 0xe2, 0x70, 0xe8, 0x4f, 0x64, 0x7e, 0x24, 0x93, 0x4a, 0x06, 0xad, + 0xfd, 0x2e, 0x3b, 0x10, 0xd2, 0xaa, 0x6a, 0xdd, 0x87, 0xb9, 0x72, 0xec, + 0xe9, 0xf1, 0x17, 0x4e, 0xa4, 0xbe, 0x40, 0xa6, 0xa0, 0x01, 0xfc, 0xd4, + 0xd2, 0x1c, 0x42, 0x07, 0x03, 0x09, 0x91, 0x26, 0x88, 0x7c, 0xf9, 0xe5, + 0xa9, 0xea, 0xa1, 0x8a, 0x34, 0x18, 0xd6, 0x1e, 0xf5, 0x9b, 0xc4, 0x37, + 0x09, 0x0d, 0x0d, 0x3c, 0x22, 0x08, 0x2d, 0xb4, 0x98, 0x70, 0xe8, 0x68, + 0x01, 0x41, 0x50, 0xf3, 0xfe, 0x7a, 0x4e, 0xa9, 0xce, 0x64, 0x00, 0xb9, + 0xdd, 0xa5, 0x06, 0xd6, 0xc7, 0xbd, 0xdf, 0xd2, 0x51, 0x24, 0xa4, 0xfa, + 0x54, 0x77, 0xc1, 0xf6, 0xa4, 0x5f, 0x84, 0x86, 0xd3, 0x31, 0xd8, 0xff, + 0x87, 0xd2, 0xc7, 0x4f, 0xdd, 0xc3, 0xce, 0x9a, 0x04, 0x46, 0xaf, 0x52, + 0x71, 0xe9, 0x11, 0x42, 0x6d, 0xe2, 0x77, 0x11, 0x3f, 0x19, 0x29, 0x44, + 0xb9, 0xe6, 0xcc, 0xda, 0x6e, 0xd1, 0x27, 0xc7, 0x56, 0xd5, 0x36, 0x38, + 0xf6, 0xb7, 0xdb, 0x2f, 0x0e, 0xe6, 0xeb, 0x5c, 0xe0, 0xa5, 0xcc, 0xcc, + 0xea, 0xb4, 0x2e, 0x96, 0x19, 0x50, 0x12, 0xbc, 0x68, 0x07, 0xb8, 0x07, + 0x09, 0xfa, 0x48, 0x3d, 0xd7, 0xbe, 0xff, 0x64, 0xd2, 0x2d, 0x34, 0x1d, + 0x8a, 0x4b, 0x17, 0xf4, 0x66, 0x17, 0xff, 0xf2, 0xc5, 0xf9, 0xfe, 0xdc, + 0x58, 0xaf, 0xcd, 0x0d, 0xc9, 0xd0, 0xef, 0x02, 0xfe, 0xf6, 0x6c, 0xd3, + 0xd1, 0xd7, 0x6f, 0xee, 0x8f, 0xb5, 0x29, 0x44, 0x0a, 0x90, 0xd9, 0xeb, + 0x0c, 0xee, 0x80, 0x67, 0x60, 0xcb, 0x66, 0x89, 0xcb, 0x35, 0x45, 0xec, + 0x97, 0xc3, 0x02, 0xdf, 0xa6, 0x9c, 0xb1, 0x4a, 0x29, 0xac, 0x39, 0x61, + 0x33, 0xd3, 0xe5, 0x7d, 0x6d, 0x35, 0xed, 0xa3, 0x5b, 0x50, 0x69, 0xdc, + 0xd0, 0x67, 0x6d, 0xde, 0xd3, 0x8d, 0xef, 0x05, 0x03, 0x19, 0x7f, 0x5e, + 0x07, 0x3a, 0x1b, 0xf0, 0x93, 0x00, 0xc0, 0x44, 0x5c, 0x00, 0xc7, 0xd7, + 0xcd, 0x0f, 0xad, 0x5f, 0x3e, 0xb2, 0x8f, 0x40, 0xbc, 0x09, 0x76, 0xaa, + 0xeb, 0xc7, 0xef, 0xb5, 0x77, 0x69, 0x4f, 0x5c, 0x44, 0xa8, 0x29, 0xb2, + 0x34, 0xd7, 0x8f, 0xc7, 0x72, 0xfe, 0x0b, 0xf4, 0x34, 0x83, 0x1f, 0x0e, + 0x63, 0x9f, 0xce, 0xc8, 0xe2, 0x3c, 0xaa, 0x32, 0xc5, 0x9c, 0xbe, 0x39, + 0x66, 0x25, 0x3c, 0xe6, 0xf3, 0x10, 0x38, 0x4f, 0x61, 0x3b, 0x52, 0x31, + 0x34, 0x4f, 0x1b, 0x2b, 0xed, 0xe4, 0x8a, 0xe2, 0x31, 0x19, 0x26, 0x13, + 0xfa, 0xe7, 0xdc, 0x51, 0xd4, 0x3f, 0xd0, 0xe3, 0x0f, 0x74, 0xa8, 0x95, + 0xfc, 0x99, 0x30, 0x96, 0x19, 0xcd, 0x82, 0x0f, 0xda, 0xc5, 0x4f, 0x55, + 0x5b, 0x81, 0xfb, 0x7e, 0xdf, 0x95, 0x2f, 0x8a, 0xda, 0xe6, 0x6e, 0x17, + 0x56, 0xe5, 0x1b, 0xdf, 0x63, 0x57, 0xc7, 0x7f, 0x8a, 0x2f, 0x39, 0xa3, + 0x41, 0xc6, 0x4d, 0xc5, 0x08, 0x87, 0xae, 0x48, 0xf2, 0xdd, 0x7b, 0x4a, + 0x28, 0x06, 0xa9, 0xc8, 0x41, 0x52, 0xde, 0x8c, 0xe0, 0x65, 0x0d, 0x23, + 0x5e, 0xa5, 0x32, 0x45, 0xb9, 0x52, 0x7d, 0xf9, 0x6a, 0xa9, 0xa8, 0x10, + 0x39, 0xe6, 0xf3, 0x78, 0x90, 0xb5, 0xaa, 0xbe, 0x88, 0x61, 0xd1, 0x21, + 0xf1, 0x5c, 0xd7, 0x8b, 0x9e, 0xaa, 0x03, 0xd8, 0x47, 0x67, 0x5a, 0x17, + 0xe5, 0x1a, 0x28, 0x4a, 0x1b, 0x13, 0x76, 0xb2, 0xaf, 0xe7, 0xc9, 0x00, + 0xf8, 0xfd, 0x70, 0xa9, 0xd0, 0x60, 0x77, 0x74, 0x89, 0x29, 0x70, 0x81, + 0x0d, 0x3d, 0x8c, 0xf2, 0xbf, 0x33, 0xb6, 0x03, 0xfa, 0x7e, 0x28, 0x9d, + 0x2a, 0xa5, 0x84, 0x28, 0x53, 0xfd, 0xd5, 0x4f, 0x14, 0x54, 0xf2, 0xd1, + 0xe9, 0x11, 0xac, 0x9c, 0x0e, 0x38, 0x50, 0x27, 0x0c, 0xe7, 0xa6, 0x53, + 0x06, 0x2b, 0x47, 0xe6, 0xcd, 0xa5, 0x11, 0xb2, 0xf9, 0x3c, 0x8e, 0xa1, + 0xd9, 0x97, 0x2c, 0xfc, 0x3c, 0x3f, 0x17, 0x3b, 0x8d, 0x8a, 0xf2, 0x28, + 0x7e, 0xf7, 0x77, 0xf3, 0xd5, 0x02, 0x8f, 0x9d, 0x63, 0x0c, 0x47, 0xc0, + 0x13, 0x2d, 0x8c, 0x3a, 0xd5, 0xbd, 0x49, 0xc7, 0xf5, 0x91, 0xe3, 0x17, + 0xa7, 0x0c, 0x96, 0xe2, 0xbb, 0x20, 0x71, 0xcc, 0x32, 0xcc, 0x81, 0x5e, + 0xee, 0xe0, 0x7c, 0x02, 0x66, 0x99, 0x5f, 0x8b, 0x41, 0x5c, 0x08, 0x46, + 0x62, 0x41, 0x04, 0xe8, 0x74, 0xb2, 0x80, 0xdc, 0x89, 0x74, 0x7a, 0x58, + 0x51, 0xa4, 0x7d, 0xc6, 0x6f, 0x05, 0x88, 0x42, 0x84, 0x58, 0xec, 0x66, + 0x9e, 0xdf, 0x66, 0x46, 0xfd, 0xf8, 0x5e, 0xc7, 0x51, 0xe1, 0x69, 0xdc, + 0x32, 0x10, 0xc5, 0x4f, 0xbc, 0x64, 0x46, 0x37, 0x00, 0x80, 0xab, 0x5c, + 0x5f, 0x44, 0xec, 0x8a, 0x13, 0x21, 0xf9, 0xe7, 0xd8, 0x11, 0xbb, 0xef, + 0x2a, 0x05, 0x65, 0x85, 0x9f, 0x11, 0x28, 0x2f, 0x7d, 0xff, 0x91, 0x93, + 0x6f, 0x2f, 0x1f, 0xa2, 0xa0, 0x15, 0xc9, 0x92, 0xfe, 0x55, 0x81, 0xa1, + 0x44, 0x4b, 0x78, 0x47, 0x80, 0x8d, 0x93, 0x1d, 0x0d, 0xf8, 0xed, 0xf0, + 0x80, 0x37, 0x9a, 0x3e, 0x48, 0x81, 0x38, 0x33, 0x25, 0x21, 0x21, 0xff, + 0x48, 0xcb, 0x72, 0x66, 0x7a, 0x74, 0x75, 0xfc, 0xee, 0x65, 0x30, 0x21, + 0x52, 0x6a, 0xee, 0xd9, 0x53, 0x34, 0x07, 0x09, 0x20, 0xad, 0xc4, 0xf7, + 0xda, 0x47, 0xf1, 0x2a, 0x5f, 0xa4, 0xf1, 0x8d, 0xfd, 0x93, 0xc1, 0xe9, + 0x24, 0xe6, 0x8b, 0x7e, 0x8c, 0xce, 0x17, 0x80, 0x9c, 0xe6, 0x5f, 0x1c, + 0x54, 0xad, 0x86, 0xec, 0xac, 0x77, 0xb6, 0x99, 0xe3, 0x84, 0xa6, 0xea, + 0xc2, 0x52, 0xa0, 0x35, 0x1c, 0xba, 0xa8, 0xa5, 0x2e, 0x46, 0xba, 0xfb, + 0x57, 0x89, 0xaf, 0xc3, 0xf9, 0x8b, 0x8d, 0x91, 0xc0, 0xa5, 0x19, 0xdc, + 0xb6, 0x18, 0x02, 0x14, 0x9d, 0x51, 0xef, 0x95, 0x6b, 0x40, 0x2c, 0x91, + 0xee, 0xcf, 0xce, 0x1f, 0x10, 0xae, 0xb9, 0x46, 0x89, 0x29, 0x3e, 0xac, + 0xa0, 0x2d, 0x89, 0x79, 0x27, 0xf2, 0xe2, 0x98, 0xad, 0xa4, 0x50, 0xb3, + 0x78, 0xa1, 0x53, 0x85, 0xb7, 0xde, 0xee, 0x29, 0x1d, 0x8d, 0xc7, 0x04, + 0x00, 0x4c, 0x64, 0xf1, 0x40, 0x6b, 0x75, 0xce, 0xd4, 0x99, 0x4a, 0xeb, + 0x92, 0x87, 0xb4, 0xb4, 0xf0, 0x96, 0xa9, 0xed, 0x4a, 0x26, 0xb8, 0xf1, + 0x93, 0xba, 0xb8, 0xb8, 0x38, 0xed, 0x8e, 0xe2, 0xda, 0x2d, 0xd7, 0xc2, + 0x40, 0xdc, 0x33, 0x6c, 0xbd, 0x5f, 0x59, 0x54, 0x3b, 0x5f, 0x59, 0xa2, + 0x8b, 0x29, 0x4a, 0xec, 0xea, 0x3b, 0xa7, 0xe7, 0xeb, 0x0c, 0x11, 0xa7, + 0xec, 0x01, 0xbb, 0x0a, 0x5d, 0xa6, 0x20, 0x63, 0x54, 0x86, 0x1c, 0x60, + 0xab, 0xbe, 0x39, 0x6f, 0xb0, 0x4a, 0x48, 0x60, 0x94, 0x14, 0x8b, 0x32, + 0x54, 0x6d, 0x4c, 0xda, 0xf0, 0x25, 0xd8, 0xbc, 0xdb, 0xa1, 0x9e, 0xb8, + 0xfd, 0xe5, 0x16, 0xc8, 0xe6, 0xb0, 0xc6, 0x2b, 0x9f, 0x2b, 0x48, 0x08, + 0x70, 0x82, 0x16, 0xe3, 0x7c, 0xff, 0xbe, 0xc8, 0x71, 0xb3, 0x6b, 0xda, + 0xca, 0x66, 0x13, 0x8e, 0x4e, 0x44, 0x84, 0xfc, 0xac, 0xeb, 0x89, 0x59, + 0xf8, 0xe9, 0x84, 0x83, 0xe0, 0x03, 0x02, 0xb0, 0x45, 0x6a, 0xce, 0x27, + 0x4c, 0x6a, 0xce, 0xc5, 0x47, 0x66, 0xc4, 0x63, 0x9f, 0xb0, 0x24, 0x20, + 0x02, 0xab, 0x2d, 0x06, 0x27, 0xca, 0x23, 0xb1, 0xd0, 0xeb, 0x33, 0x71, + 0x2d, 0x5d, 0x5e, 0x96, 0x37, 0xba, 0x85, 0x3c, 0x11, 0x8d, 0xe7, 0xd7, + 0x50, 0x0c, 0x15, 0xa6, 0x48, 0x4b, 0x95, 0xf3, 0xe1, 0xe8, 0xb7, 0x3a, + 0xdc, 0xd6, 0xb8, 0xb8, 0x38, 0x29, 0x45, 0x45, 0xc5, 0xce, 0xea, 0x8e, + 0xe1, 0x89, 0x89, 0x81, 0x5c, 0x21, 0xdf, 0xf3, 0xc7, 0xe3, 0x1a, 0x28, + 0x09, 0x02, 0x00, 0xc2, 0xa8, 0x3c, 0x92, 0xe9, 0x10, 0x14, 0x01, 0xb3, + 0xcf, 0xc2, 0xe5, 0x73, 0x21, 0xfc, 0x84, 0x91, 0xa0, 0xd6, 0x77, 0xa2, + 0xcb, 0xef, 0x01, 0x4f, 0x71, 0xd9, 0x89, 0x02, 0x24, 0xe2, 0x88, 0xe5, + 0x4d, 0x64, 0x39, 0xab, 0xf9, 0xea, 0xd1, 0xbc, 0xc0, 0xa6, 0x11, 0xb3, + 0xe0, 0x05, 0x9d, 0x6e, 0x3e, 0x2e, 0x5a, 0x5a, 0x84, 0x64, 0x5a, 0x85, + 0xde, 0x38, 0x52, 0x81, 0xe9, 0x5f, 0x0a, 0xde, 0xb1, 0xcc, 0xdf, 0xc6, + 0xc9, 0x3e, 0x21, 0xb6, 0xb5, 0xde, 0xf8, 0x80, 0x10, 0x82, 0xb1, 0xda, + 0xc6, 0x53, 0x46, 0xa7, 0x27, 0x00, 0x4e, 0xa0, 0x13, 0xc9, 0x94, 0x14, + 0xfe, 0xbb, 0x2a, 0xda, 0x50, 0x0c, 0x47, 0x2e, 0x1b, 0x65, 0x25, 0xa0, + 0x6d, 0x8e, 0xe2, 0x8f, 0x9b, 0xe3, 0x25, 0xdf, 0x7f, 0x1d, 0xb1, 0x44, + 0x5c, 0xbd, 0xbf, 0xb5, 0xeb, 0xed, 0x80, 0xd9, 0xc7, 0x79, 0xaa, 0x95, + 0xed, 0xf7, 0x2f, 0xd4, 0xd4, 0x10, 0x3b, 0x61, 0x0f, 0xe4, 0xe7, 0xc1, + 0x20, 0x14, 0x8d, 0x04, 0x77, 0x4a, 0x2b, 0x6e, 0x3e, 0xa3, 0x86, 0x62, + 0x80, 0x68, 0xc2, 0xd7, 0x57, 0xd7, 0x1d, 0x9e, 0x86, 0xc8, 0x03, 0xaf, + 0x97, 0x5b, 0x4b, 0x15, 0xb2, 0x10, 0x06, 0x0c, 0x4b, 0xe2, 0xf8, 0x78, + 0x10, 0xb4, 0xab, 0xbc, 0x55, 0x05, 0x3d, 0x5c, 0x58, 0x24, 0x91, 0xf4, + 0x2d, 0xb2, 0x0d, 0x15, 0x61, 0xd4, 0xf8, 0x00, 0xb5, 0xde, 0x77, 0x98, + 0xad, 0x7d, 0x94, 0xa1, 0x09, 0x36, 0xed, 0x34, 0x94, 0x1b, 0xd5, 0xad, + 0xf3, 0xe1, 0xa8, 0xc4, 0x24, 0x16, 0x45, 0x4b, 0x79, 0xf7, 0xf7, 0x5e, + 0x1f, 0x08, 0xd9, 0xfb, 0x9b, 0x26, 0x5a, 0xc1, 0x30, 0xf1, 0xd9, 0xcb, + 0xd1, 0xdf, 0xc4, 0xef, 0xde, 0x05, 0x63, 0x38, 0xc1, 0x01, 0xe2, 0xb2, + 0xf9, 0xd1, 0x93, 0x47, 0x18, 0x3d, 0x79, 0xa1, 0x96, 0x8a, 0x61, 0x8b, + 0x21, 0xf1, 0x7a, 0x69, 0x6a, 0x1f, 0x31, 0xeb, 0x1d, 0x8c, 0x25, 0x5e, + 0x0f, 0xc8, 0x85, 0x47, 0xc1, 0xcb, 0xf7, 0x7f, 0xba, 0x6d, 0x79, 0x7b, + 0x7d, 0xaa, 0x73, 0xd9, 0x95, 0xd5, 0x4d, 0xeb, 0x99, 0x29, 0x92, 0x06, + 0xc6, 0x6d, 0xaf, 0x09, 0xca, 0x57, 0x91, 0x29, 0x3f, 0x95, 0x5f, 0x0b, + 0x07, 0x61, 0xb5, 0xe1, 0x27, 0x50, 0xdb, 0xbd, 0x1b, 0x95, 0xa3, 0xcf, + 0xfd, 0xaa, 0x98, 0xfa, 0xff, 0xa6, 0x12, 0x90, 0xbe, 0xfd, 0x41, 0xa1, + 0xa7, 0x44, 0x03, 0x7d, 0x9a, 0x07, 0x9c, 0xaa, 0xb3, 0x07, 0x72, 0x67, + 0x43, 0x62, 0x6a, 0x2c, 0x8d, 0x65, 0xa8, 0xc1, 0x7a, 0x8e, 0xd5, 0x75, + 0x4f, 0x1e, 0x20, 0x5a, 0xa9, 0xe1, 0x51, 0x15, 0x4c, 0x33, 0x88, 0x13, + 0xa0, 0x0f, 0x9b, 0x9b, 0x59, 0xef, 0x05, 0x53, 0xf2, 0xa7, 0x5c, 0x3b, + 0x09, 0x39, 0x0f, 0x10, 0x54, 0x16, 0xa1, 0x0c, 0x81, 0x35, 0x31, 0x70, + 0x02, 0x22, 0x65, 0xb1, 0x8e, 0x78, 0xa3, 0x18, 0x6f, 0x82, 0xd7, 0xe2, + 0xe2, 0x77, 0x26, 0x2e, 0x2e, 0x5c, 0x4c, 0x4c, 0x4c, 0xe8, 0x5e, 0x6f, + 0x8a, 0x6c, 0x89, 0xee, 0x24, 0x9b, 0xcd, 0x3c, 0xdd, 0x81, 0x1b, 0x3f, + 0x09, 0x9f, 0xca, 0xab, 0xd6, 0xe5, 0xfd, 0xc5, 0x8e, 0xd5, 0x7c, 0x19, + 0xe6, 0xe5, 0xe5, 0x65, 0xad, 0xfb, 0xb1, 0x06, 0x20, 0x88, 0x22, 0xf4, + 0x77, 0x9d, 0xce, 0x14, 0x8b, 0xe7, 0x18, 0x12, 0x31, 0x9d, 0xec, 0x81, + 0x81, 0x68, 0x91, 0x75, 0x8e, 0x63, 0xe3, 0x9e, 0x08, 0x6a, 0x04, 0xcc, + 0xa1, 0xb6, 0x77, 0x3a, 0xff, 0x2b, 0x37, 0x5d, 0xea, 0x75, 0x77, 0x38, + 0x06, 0xe8, 0x85, 0xc0, 0x74, 0x3a, 0x95, 0xe8, 0x7c, 0xbf, 0x8e, 0x1a, + 0x10, 0x44, 0x2d, 0xb3, 0xdc, 0x60, 0x8d, 0xcd, 0x49, 0x14, 0xbb, 0xce, + 0x01, 0x6e, 0x83, 0x7e, 0x1e, 0x00, 0x8a, 0xc1, 0xae, 0xfb, 0x93, 0xdb, + 0xd7, 0x87, 0x97, 0x23, 0x7d, 0xc4, 0x3c, 0x0e, 0x0d, 0x34, 0x57, 0x2e, + 0xab, 0x9f, 0xbe, 0xff, 0x19, 0x73, 0xe0, 0x33, 0x86, 0x95, 0x6c, 0x5e, + 0xeb, 0x0c, 0xea, 0x71, 0xea, 0xa7, 0x42, 0x14, 0xb3, 0x85, 0xa1, 0xa8, + 0xc9, 0x27, 0xc8, 0x7a, 0xe3, 0xa5, 0xff, 0xcf, 0xdb, 0xec, 0xfb, 0x1c, + 0x4e, 0xf7, 0x38, 0xf1, 0xf0, 0xf0, 0xf6, 0x6e, 0xaf, 0xfc, 0xae, 0x67, + 0xa4, 0xa7, 0x6d, 0x1a, 0x21, 0xfc, 0xe8, 0x03, 0x91, 0xc2, 0x55, 0x88, + 0x83, 0x88, 0x31, 0xec, 0x17, 0xa4, 0x75, 0x39, 0x27, 0xb2, 0x96, 0xfc, + 0x42, 0xa7, 0xcd, 0x4c, 0xa6, 0x27, 0x8a, 0xa8, 0x79, 0xf9, 0x08, 0x8c, + 0x59, 0xd6, 0x7e, 0x89, 0xb0, 0x2f, 0xc4, 0x76, 0x9b, 0x3f, 0x76, 0x21, + 0x9c, 0xcf, 0x41, 0x44, 0x49, 0x4f, 0x8f, 0xc4, 0x62, 0x2a, 0xf7, 0x94, + 0x93, 0x19, 0x11, 0x86, 0x38, 0x76, 0xd0, 0x54, 0x0a, 0xdf, 0xf1, 0x82, + 0x21, 0x65, 0xba, 0x13, 0x6e, 0xff, 0x68, 0x27, 0x06, 0xbe, 0x14, 0x66, + 0x97, 0x06, 0x57, 0x44, 0xbb, 0x4d, 0x71, 0x2f, 0x02, 0x62, 0x21, 0x1f, + 0x4e, 0x1b, 0x5c, 0xb2, 0x16, 0xdb, 0x96, 0xf5, 0xe5, 0x29, 0x91, 0xb7, + 0x98, 0xe0, 0xe0, 0x77, 0xcd, 0x79, 0xc7, 0xad, 0xfb, 0xb9, 0x5f, 0x44, + 0x45, 0x83, 0xec, 0xb3, 0xea, 0x00, 0x21, 0xb2, 0x0b, 0xcf, 0xa8, 0xcd, + 0x79, 0x65, 0x30, 0x85, 0xa1, 0x60, 0xae, 0x59, 0x5e, 0xd3, 0xa3, 0x12, + 0x5c, 0xdd, 0x4a, 0xee, 0xd3, 0x82, 0x51, 0xe7, 0xd0, 0x04, 0x84, 0x22, + 0xfd, 0x4a, 0x0b, 0x0f, 0x20, 0x5e, 0x34, 0x7c, 0x46, 0x46, 0x06, 0x64, + 0x54, 0x79, 0xf9, 0x0f, 0xd0, 0xa3, 0x70, 0xe0, 0x9e, 0xde, 0x45, 0xc1, + 0x88, 0x5b, 0x54, 0x85, 0xcb, 0x77, 0xac, 0x36, 0x4d, 0x63, 0xc6, 0x23, + 0x55, 0x51, 0x63, 0x84, 0xa0, 0xa4, 0x59, 0xf6, 0x67, 0xc7, 0x0c, 0xcb, + 0x51, 0x3a, 0x2c, 0xf1, 0xaf, 0xfa, 0xee, 0x67, 0xcb, 0x44, 0xf4, 0xa9, + 0x2f, 0xbf, 0x6f, 0x0f, 0x0e, 0x0e, 0x7c, 0xf8, 0xd2, 0x56, 0xf4, 0x5a, + 0x0d, 0x7e, 0xa8, 0xa9, 0xb1, 0x7c, 0xb2, 0x0e, 0xa2, 0x2b, 0xf0, 0xc5, + 0xfc, 0xd6, 0x91, 0xf0, 0x11, 0x51, 0xec, 0x89, 0xbe, 0x49, 0xf3, 0xf7, + 0x66, 0x64, 0xe7, 0x8f, 0xc3, 0xe8, 0x4f, 0x94, 0xfd, 0x4f, 0x10, 0x12, + 0x92, 0xef, 0x6f, 0xfb, 0x54, 0x79, 0xdd, 0x68, 0xbb, 0xb4, 0x38, 0xd6, + 0xaa, 0xa2, 0xa2, 0x62, 0x57, 0xa3, 0x5e, 0x61, 0x61, 0x7d, 0xe3, 0x92, + 0x84, 0x00, 0x89, 0xdd, 0x25, 0x24, 0x6d, 0x3d, 0xef, 0xe3, 0x3e, 0x96, + 0xc0, 0xf0, 0x01, 0xd0, 0x9d, 0x3e, 0x0c, 0x12, 0x25, 0xea, 0xdf, 0xa0, + 0x5c, 0xd2, 0xd3, 0xa6, 0xb7, 0xfb, 0x1d, 0xf4, 0xe6, 0xbc, 0xa2, 0xda, + 0x5a, 0x0c, 0x3e, 0x3e, 0xbe, 0x40, 0xfb, 0x72, 0x89, 0xc6, 0xb6, 0x4d, + 0xb4, 0xe6, 0xbc, 0xe2, 0xef, 0x2e, 0x53, 0x15, 0x81, 0x20, 0x6e, 0x1b, + 0xf7, 0x1d, 0x75, 0x0b, 0xd7, 0x8b, 0xf7, 0x49, 0xc5, 0xf1, 0xef, 0x83, + 0xc6, 0x96, 0xfe, 0xd4, 0x79, 0x00, 0xf3, 0xd2, 0x05, 0x1d, 0x6a, 0xd7, + 0x0a, 0x20, 0x48, 0x86, 0xea, 0x6e, 0x9d, 0x66, 0xd4, 0x0c, 0xad, 0x00, + 0x0e, 0x02, 0x0d, 0x44, 0x4f, 0x5b, 0x71, 0x46, 0xc4, 0xc6, 0x4a, 0xee, + 0x4f, 0xe6, 0xcc, 0x54, 0xa8, 0x33, 0x40, 0x1f, 0xbc, 0xd5, 0xd5, 0xd5, + 0x35, 0xe1, 0x95, 0x71, 0x5d, 0x40, 0x2b, 0x28, 0x5b, 0x31, 0xe6, 0x4d, + 0x57, 0xab, 0x85, 0x3b, 0x2e, 0x1c, 0xa7, 0xe1, 0xb6, 0xd3, 0x78, 0x91, + 0x2b, 0x07, 0xe6, 0x1c, 0xc8, 0x54, 0x7d, 0xc6, 0x71, 0xbe, 0x8b, 0x30, + 0xd9, 0x9b, 0x02, 0x58, 0x02, 0xa6, 0x1b, 0x64, 0x3e, 0x2c, 0x06, 0x3c, + 0xd0, 0xe2, 0x20, 0xb7, 0x15, 0x88, 0x23, 0x5e, 0x18, 0x58, 0xaa, 0x56, + 0x6f, 0x75, 0x95, 0x6e, 0x56, 0x2d, 0xd6, 0x41, 0x62, 0x86, 0x54, 0x00, + 0xaf, 0xa6, 0xe3, 0x12, 0xd9, 0xa1, 0xf3, 0x46, 0x43, 0x77, 0xbf, 0xa1, + 0x22, 0xa2, 0x30, 0x22, 0x0c, 0x05, 0x1f, 0xb4, 0xa0, 0x69, 0x18, 0xd6, + 0x63, 0x04, 0xf8, 0xfb, 0x57, 0x2b, 0xd9, 0x20, 0xdb, 0x92, 0xc4, 0xf5, + 0xcb, 0x81, 0xf0, 0x77, 0xf6, 0x50, 0x7c, 0xac, 0x81, 0x18, 0x75, 0xd1, + 0xe9, 0x3f, 0x51, 0xa7, 0xd7, 0xe3, 0x7a, 0x24, 0x42, 0xee, 0x06, 0x93, + 0x10, 0x47, 0xff, 0xf7, 0x6b, 0xb5, 0xd1, 0x26, 0xea, 0x5c, 0x59, 0x33, + 0xcc, 0x30, 0xdb, 0x79, 0x12, 0xaa, 0x5e, 0x3f, 0x90, 0x09, 0x12, 0x40, + 0x04, 0xc3, 0xa0, 0x63, 0xf7, 0x4b, 0x38, 0x08, 0x64, 0xf2, 0x6f, 0x77, + 0xb7, 0xc7, 0xa6, 0xf3, 0x35, 0xbd, 0x2e, 0x3f, 0x1f, 0x70, 0xb5, 0x37, + 0xf1, 0x05, 0xd8, 0x64, 0x7f, 0xf1, 0x7c, 0x35, 0xf5, 0x96, 0x3a, 0x0e, + 0x09, 0x9c, 0xc3, 0xcc, 0x83, 0x03, 0xf8, 0x94, 0x71, 0x86, 0x02, 0x5d, + 0xb0, 0x81, 0x6c, 0x79, 0x8c, 0xae, 0x59, 0xe3, 0xaf, 0x71, 0xc0, 0xa8, + 0x2f, 0x2a, 0xe3, 0x8b, 0xbb, 0xc0, 0xa3, 0x87, 0x23, 0x8b, 0xab, 0x1a, + 0xc4, 0x2f, 0xb9, 0xc4, 0x30, 0xf2, 0x35, 0x16, 0x04, 0xab, 0xa8, 0x3f, + 0x7d, 0xda, 0x89, 0x13, 0x00, 0xd7, 0xda, 0xdb, 0x36, 0xea, 0x40, 0x1f, + 0x5d, 0xb6, 0xb6, 0xb6, 0x0e, 0x0f, 0x0f, 0x8b, 0x6a, 0x6b, 0xef, 0xd2, + 0x74, 0x54, 0x50, 0x89, 0x45, 0xf8, 0xfd, 0x32, 0x1f, 0x3b, 0x14, 0x29, + 0x2e, 0x96, 0x77, 0xff, 0x32, 0xdf, 0x15, 0x82, 0x1c, 0xee, 0x5b, 0x9e, + 0x90, 0xe0, 0xa0, 0x6d, 0xe1, 0x3a, 0xd9, 0x19, 0x44, 0x43, 0x44, 0xd7, + 0x2d, 0x7b, 0xb6, 0x59, 0xff, 0x91, 0x68, 0x48, 0x62, 0x98, 0x94, 0x08, + 0x02, 0xde, 0x87, 0x12, 0x97, 0x34, 0x7a, 0x6d, 0x26, 0xdd, 0xaf, 0x7a, + 0x05, 0xd3, 0x16, 0x80, 0xed, 0xb9, 0xa0, 0xb2, 0x56, 0x59, 0xf3, 0x2d, + 0xed, 0xc1, 0x14, 0xfa, 0xc9, 0x15, 0x0b, 0x51, 0xef, 0x08, 0x36, 0x05, + 0x4e, 0xa3, 0xba, 0xa7, 0x01, 0x0b, 0xee, 0xac, 0xc4, 0xdc, 0xdc, 0x38, + 0x88, 0x77, 0x6a, 0x31, 0xe2, 0x01, 0x79, 0x4d, 0x57, 0x3f, 0xda, 0xb8, + 0x2f, 0xb1, 0x69, 0x1c, 0x3f, 0xe4, 0xc0, 0xc3, 0xfb, 0x3e, 0xb7, 0xd5, + 0x67, 0x32, 0xb8, 0x8d, 0xad, 0xcb, 0xe1, 0xe2, 0x9f, 0xfd, 0x8b, 0x81, + 0x0f, 0xd4, 0xae, 0x63, 0x72, 0x8e, 0x6b, 0x16, 0x79, 0xc0, 0x4c, 0x92, + 0x10, 0xe9, 0x0b, 0xc5, 0x38, 0x4b, 0x9d, 0xe6, 0x5c, 0xb4, 0x96, 0x4f, + 0x32, 0x8a, 0x8a, 0xca, 0x6c, 0x83, 0x6f, 0x71, 0x99, 0xb1, 0x99, 0x78, + 0xd4, 0xc3, 0x89, 0x1e, 0x7c, 0x17, 0xbe, 0x12, 0xe4, 0xac, 0xe8, 0x75, + 0xff, 0xde, 0x3e, 0x75, 0x74, 0xf9, 0x53, 0xd0, 0x96, 0x42, 0xd0, 0x9f, + 0xfe, 0xd7, 0x9c, 0x18, 0xd8, 0xef, 0x69, 0x84, 0x28, 0x06, 0x55, 0x6a, + 0xdc, 0x81, 0x82, 0xf4, 0x36, 0xe3, 0x10, 0x4a, 0xa2, 0x1c, 0x35, 0x87, + 0x84, 0x08, 0x68, 0xdb, 0x05, 0x2f, 0x04, 0x07, 0xb7, 0x05, 0x54, 0x2f, + 0x91, 0xdf, 0x13, 0xef, 0x97, 0xe4, 0xc0, 0x6c, 0x89, 0xdb, 0xf0, 0x63, + 0x25, 0xab, 0x40, 0x6f, 0xe1, 0x40, 0x08, 0x50, 0x28, 0x46, 0xda, 0x3c, + 0x7d, 0xea, 0x1c, 0xc1, 0x7e, 0x09, 0xd2, 0xc0, 0x40, 0x96, 0xef, 0x3b, + 0xde, 0x93, 0x96, 0x9a, 0xda, 0xf3, 0xcf, 0x48, 0x7f, 0xf1, 0x01, 0x5d, + 0xca, 0x95, 0x02, 0x12, 0xef, 0x68, 0x92, 0xab, 0x34, 0xa2, 0x65, 0x4a, + 0x90, 0xdb, 0xf3, 0x17, 0x9a, 0x9a, 0xa2, 0x0a, 0x6f, 0x94, 0xbf, 0xcd, + 0x70, 0x6b, 0x55, 0xf9, 0xfc, 0xdb, 0xd5, 0x2f, 0x7f, 0x13, 0x11, 0x85, + 0x95, 0x42, 0x5a, 0x8f, 0x4e, 0xfd, 0xe9, 0xc0, 0xa0, 0x4a, 0x97, 0xf9, + 0xa6, 0x8a, 0x23, 0x67, 0x4f, 0xb3, 0xf3, 0xb3, 0x7a, 0x43, 0x0a, 0x29, + 0x07, 0x03, 0xd4, 0x58, 0xf8, 0x51, 0xdf, 0x53, 0xbb, 0x5e, 0xc7, 0x7d, + 0x62, 0x9b, 0xaa, 0x40, 0xd3, 0x82, 0x3b, 0x8f, 0x09, 0x70, 0x4e, 0x03, + 0x48, 0x97, 0xe7, 0x63, 0xcd, 0x60, 0x6e, 0x11, 0x12, 0x36, 0x94, 0x82, + 0x00, 0x89, 0x9e, 0xb2, 0xf2, 0x98, 0x42, 0xd0, 0x20, 0xf7, 0xc0, 0xcb, + 0xfc, 0x8a, 0x9c, 0x1b, 0x10, 0xfa, 0x5f, 0x26, 0x15, 0x5f, 0x0f, 0x62, + 0x52, 0x15, 0x6e, 0x9d, 0xe8, 0x02, 0x7e, 0x60, 0xb5, 0xa5, 0xcd, 0x1d, + 0xbe, 0x62, 0xe0, 0x46, 0xd5, 0xd2, 0xe0, 0x02, 0xe1, 0x07, 0xf8, 0xff, + 0xe1, 0x29, 0x93, 0xc2, 0x8b, 0x47, 0x78, 0x1e, 0xcd, 0x55, 0x91, 0xc2, + 0xf5, 0xb4, 0xf6, 0x47, 0x52, 0x1f, 0x9e, 0x21, 0xa1, 0xe6, 0x38, 0x45, + 0x7f, 0xa0, 0x7c, 0x40, 0x95, 0x3d, 0x40, 0x15, 0x75, 0xbb, 0xde, 0x9a, + 0x02, 0x28, 0x48, 0x0d, 0xdc, 0x46, 0xd6, 0xe3, 0xef, 0x7e, 0xf8, 0x81, + 0x21, 0x5e, 0xa1, 0xa6, 0x57, 0x58, 0x03, 0x62, 0x2e, 0x2c, 0x9b, 0x3d, + 0x7c, 0x25, 0xd8, 0xbe, 0x08, 0x7a, 0x46, 0xa4, 0xb9, 0x46, 0xa0, 0x10, + 0xf0, 0x55, 0x67, 0x33, 0x3d, 0x8a, 0x67, 0x68, 0xba, 0x23, 0xe1, 0xa7, + 0xb1, 0x84, 0xe2, 0x7f, 0xc9, 0xf9, 0xb4, 0x11, 0x9c, 0xd5, 0x3c, 0xf3, + 0x9d, 0x33, 0x73, 0x6b, 0x17, 0xb9, 0xd2, 0x5a, 0x30, 0x96, 0x0f, 0x2c, + 0x26, 0x4e, 0x4a, 0x2d, 0x99, 0x11, 0x16, 0xe0, 0x44, 0xe4, 0x27, 0x5c, + 0x67, 0x0f, 0x1d, 0x14, 0xe3, 0x40, 0x12, 0x55, 0x1a, 0x94, 0xec, 0x82, + 0xfd, 0xbb, 0xc2, 0x83, 0xf7, 0x56, 0xe8, 0x3f, 0x76, 0x34, 0xe9, 0x0a, + 0x78, 0x30, 0x7c, 0x5e, 0x46, 0x38, 0x62, 0xe0, 0xc9, 0xe1, 0x82, 0x9e, + 0x7b, 0xb1, 0xec, 0x96, 0x03, 0x94, 0xa1, 0xf8, 0xdd, 0x5f, 0xa2, 0x6c, + 0x5f, 0x3b, 0xe6, 0x3c, 0x79, 0xd3, 0x0c, 0x0f, 0x8f, 0x5a, 0xed, 0x2d, + 0x8d, 0xa7, 0xc2, 0x94, 0x32, 0x4d, 0x8c, 0x11, 0x46, 0x05, 0xba, 0x8a, + 0x5a, 0xaa, 0x0c, 0xdc, 0xfc, 0x68, 0x49, 0x07, 0x1d, 0x35, 0x31, 0xc4, + 0x47, 0xad, 0x4e, 0x1a, 0x2b, 0x45, 0x96, 0x41, 0x21, 0xa6, 0xf2, 0x13, + 0xb4, 0x45, 0xa5, 0x7a, 0x5d, 0x0a, 0xdb, 0xa9, 0x05, 0x60, 0x78, 0x82, + 0x25, 0x7c, 0xc4, 0xae, 0x75, 0x45, 0x17, 0xd2, 0xd7, 0x4e, 0x26, 0x77, + 0x5c, 0xb5, 0x8b, 0xa1, 0x8c, 0x0c, 0xad, 0xc2, 0xbb, 0x0a, 0x68, 0xab, + 0x14, 0x4e, 0xc0, 0x76, 0x3d, 0x4c, 0x58, 0x63, 0xbe, 0xd6, 0x0f, 0xdc, + 0x63, 0xcf, 0x11, 0x12, 0x74, 0xca, 0x50, 0x5e, 0xdb, 0x59, 0xba, 0x8a, + 0x51, 0xff, 0x60, 0x0a, 0x8f, 0x1b, 0x23, 0xba, 0x80, 0x30, 0xc8, 0xcf, + 0xef, 0xf3, 0xf6, 0x41, 0x36, 0xed, 0x21, 0x06, 0x18, 0xad, 0x1c, 0x55, + 0xd1, 0x2d, 0x10, 0xff, 0x43, 0x8b, 0xc4, 0x10, 0x3f, 0xe9, 0xe7, 0x89, + 0x43, 0x30, 0x9d, 0xb4, 0x9d, 0x81, 0x09, 0xba, 0xea, 0x45, 0x22, 0x43, + 0x1b, 0x72, 0x54, 0x16, 0x77, 0x0c, 0x22, 0x40, 0x31, 0x40, 0x04, 0x78, + 0x87, 0xd1, 0xdc, 0x9b, 0x3c, 0x38, 0xba, 0xfc, 0xf8, 0x82, 0x48, 0xe9, + 0x51, 0xf8, 0x51, 0x1c, 0x13, 0x97, 0xec, 0xc8, 0x85, 0x7c, 0x1f, 0x6f, + 0x1f, 0xcc, 0xd4, 0xcf, 0x04, 0x99, 0xa6, 0x68, 0x62, 0xa2, 0xea, 0x1d, + 0x1d, 0x8e, 0xf1, 0x3e, 0x8c, 0xd1, 0xc4, 0x9e, 0xff, 0x74, 0xda, 0x0c, + 0x16, 0x37, 0x64, 0x25, 0x08, 0x85, 0xf3, 0xdb, 0xc7, 0x9c, 0x07, 0x71, + 0xbe, 0x88, 0x8b, 0x83, 0x7f, 0x2d, 0xae, 0xdf, 0x04, 0xbd, 0xaa, 0x10, + 0xe7, 0xff, 0xf9, 0x13, 0x92, 0x5d, 0x37, 0x6c, 0x32, 0x29, 0xf7, 0x29, + 0x93, 0x49, 0x43, 0x42, 0x32, 0xb4, 0xd0, 0xf6, 0x09, 0xae, 0xb5, 0x8f, + 0x2a, 0x14, 0x23, 0x0b, 0x0a, 0x54, 0x6f, 0x5a, 0x49, 0xd1, 0x42, 0x3f, + 0x45, 0xeb, 0xf9, 0x3c, 0x51, 0x8c, 0x5a, 0x8e, 0x2e, 0xf2, 0xfd, 0x48, + 0xf4, 0x0b, 0x78, 0x94, 0x6d, 0xdc, 0x4f, 0x58, 0x82, 0x68, 0x89, 0x01, + 0x5d, 0x4f, 0xe6, 0x28, 0xa3, 0x31, 0xb4, 0xad, 0x5f, 0xa0, 0xcd, 0xff, + 0x02, 0x14, 0x52, 0x9f, 0xe0, 0xc4, 0x08, 0xf6, 0x7a, 0x94, 0x9f, 0x11, + 0x20, 0x0b, 0x37, 0x6a, 0x25, 0xe8, 0x60, 0xc4, 0xb8, 0xe5, 0x0f, 0x18, + 0x1e, 0x61, 0xe9, 0xbd, 0x6c, 0x14, 0xd8, 0x85, 0xce, 0xc9, 0xae, 0xa2, + 0x02, 0x4f, 0x73, 0x92, 0x75, 0xdd, 0xf4, 0xfb, 0x3d, 0x26, 0xc4, 0x07, + 0xb4, 0x8c, 0x8c, 0xce, 0xce, 0x60, 0x52, 0x61, 0x00, 0x3f, 0x5f, 0xda, + 0x70, 0x11, 0x8a, 0xb4, 0xc1, 0xff, 0x81, 0x0c, 0xf5, 0x08, 0xc1, 0x67, + 0xcf, 0x0f, 0x5d, 0x11, 0x10, 0xbb, 0x68, 0x68, 0x34, 0x09, 0xa5, 0xd5, + 0xfd, 0xad, 0x01, 0xe4, 0x97, 0x49, 0xc4, 0x37, 0xea, 0xde, 0x8d, 0x41, + 0xc9, 0x18, 0x00, 0x60, 0x52, 0xe4, 0x98, 0x52, 0x5f, 0xf2, 0x75, 0x10, + 0x04, 0xf4, 0x66, 0x24, 0x10, 0x11, 0x43, 0xea, 0xfc, 0x6e, 0xca, 0x78, + 0x69, 0x2a, 0x9a, 0x00, 0xd8, 0x1a, 0x6a, 0x04, 0x1a, 0xd7, 0x69, 0xfd, + 0x37, 0x56, 0x3e, 0x2a, 0xb2, 0x13, 0x91, 0x2d, 0xb0, 0xe9, 0xd4, 0xb0, + 0x86, 0x1a, 0x66, 0x5a, 0x95, 0x41, 0x9d, 0xa7, 0x28, 0x74, 0xe3, 0xaf, + 0x8c, 0x8a, 0x0e, 0x72, 0x7e, 0x0b, 0x00, 0xa0, 0xc9, 0xee, 0x52, 0xe7, + 0x76, 0xc3, 0xfd, 0xdf, 0x6f, 0x97, 0x08, 0xb5, 0xce, 0x89, 0x1a, 0x83, + 0xe4, 0x69, 0xa0, 0xed, 0xa4, 0x77, 0x57, 0xa9, 0xe9, 0xa5, 0x7b, 0xca, + 0xb4, 0x3f, 0x24, 0x3d, 0xaf, 0xea, 0xd4, 0x30, 0xe9, 0x77, 0xe2, 0x0e, + 0xf0, 0x77, 0x66, 0x6f, 0x63, 0x88, 0x23, 0x06, 0x87, 0xbc, 0xc3, 0xc4, + 0xb6, 0xde, 0x7c, 0x15, 0x64, 0x60, 0x18, 0xbb, 0xcd, 0x64, 0xdb, 0x58, + 0x9a, 0x63, 0x7b, 0xe0, 0x97, 0x3d, 0x10, 0x0e, 0x72, 0x5d, 0x00, 0x45, + 0x2d, 0x0d, 0xf0, 0x0b, 0x05, 0xe8, 0x49, 0x73, 0x6c, 0x20, 0x51, 0x5e, + 0x62, 0xc1, 0x85, 0x37, 0x21, 0x5d, 0xa8, 0x83, 0xf7, 0xd7, 0x96, 0x67, + 0x42, 0xb6, 0xef, 0xe1, 0x21, 0x6d, 0x44, 0x0b, 0x22, 0xee, 0x93, 0xeb, + 0x82, 0x66, 0xa3, 0x4e, 0xcf, 0x34, 0x1d, 0xbf, 0x18, 0x18, 0x47, 0x66, + 0x43, 0x58, 0x2c, 0xe2, 0x6a, 0xc3, 0x6f, 0xfe, 0x02, 0xd8, 0x77, 0xfa, + 0x05, 0xed, 0x84, 0x34, 0x6e, 0xe4, 0x46, 0x8d, 0xb9, 0x8d, 0xc8, 0xe2, + 0xd3, 0x97, 0x51, 0xf6, 0x9d, 0x3d, 0x11, 0xea, 0x59, 0x65, 0x86, 0xfc, + 0x94, 0xea, 0x75, 0x5a, 0x55, 0x74, 0x1c, 0x04, 0xc6, 0x75, 0x51, 0x00, + 0x40, 0xc8, 0x4c, 0x0c, 0x7b, 0x48, 0xe2, 0xcf, 0x80, 0xb6, 0x0c, 0x65, + 0xc9, 0x90, 0x9f, 0x2e, 0x1a, 0xfb, 0xda, 0xae, 0xc5, 0x8a, 0x0e, 0xd7, + 0xcd, 0x0a, 0x44, 0x09, 0x7f, 0xff, 0xe6, 0xd6, 0x21, 0xf4, 0x95, 0xcb, + 0x05, 0xd1, 0x20, 0x02, 0xde, 0xc1, 0xce, 0xdf, 0x07, 0xbc, 0x8e, 0x59, + 0xad, 0x53, 0x29, 0x82, 0xa7, 0x11, 0x2f, 0x5a, 0x5c, 0xf1, 0x6b, 0x40, + 0x4f, 0x5c, 0x10, 0xab, 0xfc, 0xac, 0x79, 0x1c, 0x66, 0xa0, 0x13, 0x93, + 0x52, 0x14, 0xce, 0xe4, 0x8a, 0x14, 0x0b, 0x92, 0x8a, 0x2d, 0x2a, 0x65, + 0x16, 0x75, 0x64, 0xa5, 0xa2, 0x53, 0x86, 0x8d, 0xd5, 0x09, 0x83, 0x64, + 0xce, 0x88, 0x42, 0xb8, 0x30, 0x71, 0xd1, 0x74, 0x6e, 0x02, 0x7b, 0x6c, + 0xd0, 0x4c, 0x97, 0x3b, 0x47, 0xe8, 0x0f, 0x1b, 0x36, 0x8b, 0xaf, 0x8e, + 0x9c, 0xd6, 0x12, 0x63, 0xbf, 0x6c, 0x4d, 0xa7, 0xb6, 0xe7, 0xd2, 0x39, + 0xee, 0x92, 0xe9, 0x6f, 0x91, 0xf5, 0x8a, 0x0e, 0x71, 0x6d, 0xd9, 0x49, + 0x27, 0x6f, 0xac, 0x94, 0x85, 0x63, 0xb0, 0xda, 0xd0, 0x8d, 0x19, 0xfd, + 0x84, 0xf7, 0x25, 0xa7, 0x34, 0xec, 0xee, 0x4e, 0xd6, 0xf0, 0xa2, 0x37, + 0x9f, 0x44, 0x10, 0xdf, 0xad, 0x47, 0x50, 0xbe, 0x16, 0xd5, 0xb6, 0xe0, + 0x24, 0xe7, 0x7a, 0xc1, 0x42, 0xf4, 0x0e, 0x8f, 0x48, 0x0b, 0xd1, 0xfc, + 0xff, 0x8b, 0x34, 0xe7, 0xbe, 0xc7, 0x42, 0xc7, 0x66, 0x0f, 0x65, 0xfa, + 0x32, 0x78, 0x29, 0xf7, 0xc3, 0xb1, 0x18, 0x02, 0x8f, 0x4d, 0x14, 0x56, + 0xcd, 0xba, 0x6c, 0x8d, 0x02, 0xab, 0x45, 0x43, 0x9c, 0x1a, 0x32, 0xb7, + 0xd6, 0xe4, 0x79, 0x82, 0x17, 0xb3, 0x47, 0x8c, 0xd4, 0x8a, 0x15, 0x78, + 0x19, 0xfa, 0x5c, 0x78, 0x27, 0x78, 0x80, 0xd9, 0x1e, 0x4e, 0xbe, 0xbd, + 0xb8, 0x6a, 0x83, 0xcd, 0x86, 0x04, 0x74, 0x4a, 0xe9, 0xa8, 0x40, 0x74, + 0xa3, 0xb1, 0xdc, 0x22, 0x87, 0x27, 0xc1, 0x6f, 0x49, 0xd0, 0xc3, 0xbc, + 0xee, 0x53, 0xde, 0x08, 0x08, 0x37, 0x97, 0x06, 0x65, 0xe0, 0x84, 0xfe, + 0x08, 0xcf, 0xd7, 0x4e, 0xae, 0xf0, 0x0d, 0x48, 0x76, 0xb1, 0x49, 0xc5, + 0xf2, 0x45, 0xcb, 0x13, 0xf7, 0x30, 0x48, 0x1c, 0x7b, 0x41, 0x96, 0xdc, + 0x89, 0xa7, 0xfe, 0x2c, 0x32, 0xd5, 0x67, 0xfc, 0xc0, 0x08, 0x59, 0x0d, + 0x89, 0x24, 0x64, 0x64, 0x42, 0x94, 0x43, 0xb8, 0x74, 0x7e, 0xcd, 0x98, + 0x12, 0x83, 0x89, 0xde, 0xf5, 0xa2, 0xf7, 0xe2, 0x05, 0xf9, 0x95, 0x6e, + 0x20, 0x72, 0x45, 0x5a, 0x43, 0xe8, 0xa9, 0x76, 0xf6, 0xe0, 0x82, 0x0d, + 0xd7, 0xbc, 0x0d, 0x57, 0x26, 0x8f, 0x63, 0x1c, 0xad, 0x42, 0x26, 0x05, + 0x84, 0x43, 0x43, 0x75, 0xc5, 0x54, 0xae, 0x10, 0x26, 0x01, 0x01, 0x62, + 0xd1, 0x0c, 0x62, 0xf2, 0xe1, 0xa0, 0x42, 0xdc, 0x6f, 0x0d, 0x4c, 0x4d, + 0x0e, 0x97, 0x3a, 0xe7, 0x7d, 0xb1, 0x13, 0x61, 0x2f, 0x64, 0x05, 0x22, + 0xc9, 0x42, 0xed, 0x64, 0xa9, 0xfc, 0x0e, 0x03, 0xae, 0x6f, 0xa0, 0xfb, + 0x9d, 0xe9, 0xcf, 0x69, 0x4f, 0xef, 0xde, 0xe9, 0x04, 0x3a, 0xd6, 0xe9, + 0xb5, 0xef, 0x6d, 0x27, 0xf8, 0xe1, 0xbd, 0x10, 0x3c, 0xa6, 0x27, 0x24, + 0x6c, 0xe8, 0xbb, 0xb5, 0x61, 0x4b, 0x03, 0xa2, 0xdb, 0x4c, 0x4e, 0x22, + 0xdf, 0x83, 0xff, 0x62, 0xa3, 0xaf, 0x51, 0x5a, 0x6a, 0x85, 0x7a, 0x8d, + 0xd7, 0xcd, 0xe1, 0x9f, 0x0f, 0x8b, 0x08, 0xbf, 0x03, 0x08, 0x5e, 0x4f, + 0x7f, 0x49, 0x17, 0xf6, 0xe7, 0x87, 0xa8, 0xe9, 0x99, 0x12, 0x39, 0x7c, + 0x38, 0x38, 0x35, 0x21, 0xf4, 0x31, 0x13, 0x48, 0x46, 0xcd, 0xff, 0xdb, + 0x94, 0x03, 0x49, 0x4f, 0x45, 0xd2, 0xf1, 0x26, 0x77, 0xe0, 0x75, 0x5e, + 0x67, 0x10, 0x5c, 0x52, 0x52, 0xd2, 0x5f, 0xbe, 0x66, 0x5f, 0x74, 0xd3, + 0x0f, 0x42, 0xfc, 0x8d, 0x3d, 0x27, 0x84, 0xd8, 0xd3, 0xf5, 0xae, 0xba, + 0x43, 0xf1, 0xd4, 0x00, 0x37, 0x1f, 0x58, 0xa9, 0xb5, 0xb7, 0xc2, 0x31, + 0x20, 0x38, 0x26, 0x4c, 0x68, 0xca, 0xfb, 0x22, 0xd0, 0x1c, 0x71, 0xec, + 0xd3, 0x8c, 0x79, 0x56, 0xfc, 0xcc, 0x61, 0x5c, 0x36, 0x56, 0x68, 0xbe, + 0x23, 0x7d, 0x3c, 0xd3, 0x83, 0x37, 0x07, 0xbb, 0x4b, 0x19, 0x1d, 0xf6, + 0x05, 0x7a, 0x92, 0x9b, 0xd0, 0x61, 0x1c, 0x11, 0x17, 0xf2, 0x47, 0xa9, + 0x18, 0xd1, 0x3c, 0x61, 0x7f, 0x87, 0xf4, 0x71, 0x18, 0xd1, 0x12, 0x15, + 0x4a, 0x6e, 0xee, 0xc5, 0x5b, 0xc3, 0x1a, 0x83, 0xce, 0xf3, 0x65, 0xd3, + 0xf8, 0xed, 0x1f, 0xe4, 0x01, 0x7f, 0x0f, 0xe7, 0x4a, 0x29, 0x65, 0xb0, + 0xb0, 0xb0, 0xb1, 0xd9, 0xbc, 0x2f, 0xcd, 0x80, 0xbe, 0xbc, 0xfb, 0xbc, + 0x1e, 0x8f, 0xef, 0xa0, 0xbb, 0xb7, 0x7e, 0xcd, 0x36, 0x95, 0xaa, 0xbd, + 0x9f, 0x44, 0xbf, 0x3a, 0x51, 0x10, 0x0d, 0xb5, 0xe4, 0xaa, 0x0d, 0xb7, + 0x7e, 0x6d, 0xac, 0x58, 0x87, 0xf0, 0x25, 0x74, 0x95, 0x72, 0xd0, 0xa6, + 0x25, 0xe3, 0x5f, 0x0d, 0xe6, 0x49, 0xb3, 0xa6, 0xad, 0x10, 0x16, 0x8d, + 0x59, 0x16, 0x62, 0x10, 0xbe, 0x0a, 0xb3, 0x61, 0x77, 0x48, 0x56, 0x42, + 0xc2, 0xd6, 0xe2, 0x14, 0x18, 0x42, 0x94, 0xa1, 0x97, 0x08, 0xfb, 0x7e, + 0xa0, 0x9b, 0x82, 0xfa, 0x23, 0x95, 0xcb, 0xd5, 0x00, 0x80, 0x4a, 0x3a, + 0x93, 0xd7, 0xa5, 0xca, 0xf3, 0x9b, 0xd1, 0x09, 0x07, 0xa1, 0xbc, 0x1a, + 0x65, 0xfa, 0x4a, 0x9f, 0xb6, 0x31, 0x57, 0x41, 0xa2, 0x88, 0xf8, 0xa2, + 0x50, 0x70, 0x88, 0xfc, 0xaf, 0xe2, 0x86, 0xfc, 0x7c, 0x34, 0x55, 0x98, + 0x9e, 0x5b, 0x51, 0xa7, 0xbb, 0xbc, 0x4f, 0x4e, 0xff, 0xfe, 0x79, 0xf3, + 0xf5, 0x51, 0x15, 0x6f, 0x38, 0x4f, 0x42, 0xbc, 0xb6, 0xb0, 0xa8, 0x68, + 0xa6, 0x54, 0x89, 0xbc, 0x39, 0x2f, 0x84, 0x2d, 0x7c, 0xa3, 0xd3, 0xd7, + 0xf4, 0xe6, 0x68, 0x01, 0x5a, 0x6a, 0xe9, 0x97, 0x7c, 0x86, 0x09, 0xf0, + 0x6e, 0xe5, 0xee, 0xd8, 0x89, 0x26, 0xc4, 0x25, 0xa5, 0x48, 0x17, 0x2b, + 0xb3, 0x8d, 0xc4, 0x52, 0xde, 0xbb, 0x68, 0x94, 0xa3, 0x38, 0x9c, 0xae, + 0xe0, 0x89, 0xae, 0x53, 0xd8, 0xb9, 0x48, 0x1c, 0xd3, 0xdc, 0x97, 0x7b, + 0x00, 0xc6, 0xef, 0x79, 0x5d, 0xe7, 0x6b, 0x12, 0xb5, 0xa9, 0x5a, 0xe8, + 0x7c, 0x77, 0xf2, 0x48, 0x39, 0x20, 0x48, 0xd8, 0xff, 0x71, 0xb9, 0x3a, + 0xff, 0x58, 0x6e, 0xec, 0x27, 0x13, 0x54, 0x5a, 0x74, 0xdc, 0xae, 0xda, + 0x02, 0x00, 0xdf, 0x52, 0xce, 0x57, 0xa5, 0x37, 0x7b, 0x1f, 0x35, 0x7b, + 0x88, 0x54, 0xaa, 0xb5, 0x93, 0xd3, 0xe9, 0x6f, 0xbf, 0x8a, 0x91, 0xa1, + 0xf6, 0x0f, 0x41, 0xe4, 0x8a, 0x71, 0x21, 0x81, 0x20, 0x3e, 0x62, 0x2d, + 0xae, 0x3d, 0x6f, 0x86, 0x1f, 0x12, 0xf0, 0x96, 0x66, 0x94, 0x10, 0x8b, + 0xf2, 0x86, 0xfe, 0x01, 0xa4, 0xae, 0x9d, 0x74, 0x98, 0xe5, 0xd8, 0x15, + 0x99, 0x66, 0x18, 0x40, 0x08, 0x95, 0x5b, 0x34, 0x8c, 0x2f, 0xa9, 0x6d, + 0x64, 0x1a, 0x8b, 0xbf, 0x4a, 0x8e, 0xdf, 0x69, 0x66, 0x67, 0x65, 0x79, + 0xf3, 0xe2, 0xe4, 0x41, 0xf2, 0x73, 0x69, 0x89, 0x76, 0xca, 0x68, 0xd9, + 0x14, 0x7d, 0xfc, 0xb3, 0xe7, 0x05, 0xcb, 0x7c, 0x6c, 0xec, 0x3d, 0x63, + 0xaa, 0xac, 0xb5, 0x6f, 0x4e, 0x62, 0xe2, 0x76, 0xdd, 0x15, 0xfb, 0xe0, + 0xf9, 0x20, 0xb1, 0xe3, 0x72, 0xee, 0x4a, 0xe0, 0xdd, 0x18, 0x1e, 0x0e, + 0xce, 0xa1, 0xc3, 0x25, 0xf3, 0x1b, 0x66, 0xfe, 0x37, 0xcd, 0x3a, 0x69, + 0x5c, 0xf0, 0x8c, 0xa8, 0x1f, 0x09, 0x04, 0x42, 0x96, 0xda, 0x6e, 0x6c, + 0x1d, 0x19, 0x70, 0x14, 0xba, 0xca, 0x96, 0x27, 0x47, 0x99, 0xfa, 0x3f, + 0xc9, 0x2d, 0x8d, 0x40, 0xc7, 0xa7, 0xe5, 0x79, 0xf3, 0x81, 0x49, 0x4e, + 0x4f, 0xaf, 0x70, 0xb8, 0x5a, 0x44, 0x8f, 0x95, 0x0a, 0x59, 0xa9, 0xb7, + 0x84, 0xa5, 0x3b, 0xf3, 0xe1, 0x75, 0x9c, 0xb9, 0xe3, 0xc4, 0xbc, 0x61, + 0xb1, 0xaf, 0xa0, 0x13, 0x9b, 0x48, 0xbf, 0x99, 0x4c, 0x4f, 0x3f, 0x54, + 0x9b, 0x5b, 0x57, 0x80, 0x98, 0xa4, 0xc5, 0x75, 0x3f, 0xb7, 0x56, 0x42, + 0x6a, 0x32, 0x40, 0x1c, 0xc3, 0xc4, 0x43, 0x3d, 0xa6, 0x0a, 0xd8, 0x46, + 0xfe, 0x00, 0xfd, 0x35, 0xf9, 0xbf, 0xd7, 0xc4, 0x81, 0xb6, 0xdf, 0x70, + 0x28, 0xa3, 0x72, 0x3b, 0x5f, 0x84, 0x5d, 0xfe, 0x7d, 0x05, 0x1e, 0xeb, + 0xbf, 0x57, 0xdc, 0xda, 0xba, 0x30, 0x8b, 0xcf, 0xdd, 0xd4, 0x1d, 0x18, + 0x90, 0x2a, 0xf8, 0x96, 0x72, 0x35, 0xc0, 0xbb, 0x3f, 0x18, 0xb4, 0xb6, + 0x26, 0x14, 0x6b, 0x86, 0x38, 0xf2, 0x09, 0x62, 0x12, 0xd8, 0xd6, 0xd6, + 0xb7, 0x60, 0x8a, 0x06, 0x1f, 0xb8, 0xe9, 0x83, 0xa0, 0x4b, 0x73, 0x3b, + 0x94, 0x9f, 0xcf, 0xb2, 0x9a, 0xe8, 0xfd, 0xfb, 0xd9, 0xf2, 0x5d, 0x66, + 0xbe, 0x9d, 0xae, 0xfb, 0x8a, 0xbf, 0x0d, 0xbb, 0x37, 0x8a, 0xf6, 0xcf, + 0xd6, 0x5a, 0x39, 0x56, 0x9b, 0x1d, 0x1d, 0x81, 0x06, 0xf5, 0xe6, 0xdd, + 0xd2, 0x53, 0x67, 0x55, 0x04, 0xa6, 0x88, 0xe8, 0x0b, 0xa3, 0xa4, 0xe1, + 0x53, 0x90, 0x75, 0xff, 0xf4, 0x7b, 0x31, 0xa4, 0x3c, 0x26, 0x4c, 0x10, + 0x8d, 0x15, 0x0d, 0x70, 0xdc, 0xfc, 0x12, 0x39, 0x11, 0x48, 0x92, 0x28, + 0xc0, 0x28, 0xbe, 0x56, 0x71, 0x89, 0xeb, 0x6c, 0x67, 0xc7, 0x28, 0x15, + 0x4b, 0xb4, 0x3b, 0x73, 0x85, 0x12, 0x0c, 0xad, 0x73, 0xb6, 0xdc, 0xe4, + 0x49, 0x2e, 0x08, 0x53, 0x34, 0x02, 0x9a, 0x21, 0xe8, 0x48, 0x95, 0xd2, + 0xef, 0x66, 0x40, 0x43, 0xa4, 0x71, 0xeb, 0xee, 0xf5, 0xde, 0x70, 0x09, + 0xa3, 0xf2, 0x51, 0x18, 0xb8, 0x7d, 0xae, 0xd1, 0x2c, 0x1a, 0xf7, 0xda, + 0x59, 0x5d, 0x08, 0xe5, 0xa4, 0xc6, 0x3d, 0x55, 0x81, 0xd9, 0xda, 0xf0, + 0x3d, 0x93, 0x74, 0x72, 0x72, 0xea, 0xcc, 0xb1, 0x5d, 0xa8, 0x50, 0x87, + 0x1e, 0x3d, 0xd7, 0x7a, 0x9e, 0x19, 0xb4, 0x5f, 0x20, 0x61, 0xd3, 0x2e, + 0x1b, 0x10, 0xc7, 0x58, 0x90, 0xf0, 0x8b, 0x35, 0xaf, 0xc3, 0x50, 0xf0, + 0xb3, 0xcf, 0xef, 0xb6, 0x88, 0x17, 0x94, 0xe8, 0x82, 0x1d, 0xc4, 0x91, + 0xd6, 0xa7, 0xca, 0x16, 0x72, 0xc8, 0xde, 0xbf, 0xab, 0x81, 0x11, 0xf5, + 0x30, 0xa0, 0x7c, 0x6d, 0xf7, 0x4a, 0x5d, 0xa3, 0xc4, 0x54, 0x61, 0x21, + 0xf3, 0x3b, 0xef, 0xf1, 0x79, 0x79, 0x4e, 0x48, 0xc0, 0xf0, 0x7b, 0x7b, + 0xb9, 0x23, 0xe0, 0xb6, 0x83, 0xfc, 0x2d, 0x1b, 0x11, 0x3b, 0x6e, 0x76, + 0x09, 0xf5, 0xf6, 0xf6, 0xda, 0x01, 0xd5, 0xb9, 0x68, 0x2f, 0x78, 0x62, + 0x0b, 0xa9, 0x2a, 0x96, 0x93, 0x85, 0x5b, 0xa3, 0x48, 0xff, 0x73, 0x3e, + 0xc2, 0x10, 0x63, 0xcd, 0x6a, 0x71, 0x4c, 0xb6, 0x76, 0xd0, 0xe2, 0x13, + 0x0b, 0xf1, 0xdb, 0xdf, 0x78, 0x5b, 0xcf, 0xd9, 0x2b, 0xb7, 0xd9, 0x2d, + 0xe7, 0xc9, 0x9e, 0xb7, 0x8a, 0x1d, 0x61, 0xb3, 0x61, 0x8c, 0xeb, 0xa3, + 0x85, 0x4a, 0x83, 0x29, 0x1e, 0x9f, 0x6b, 0x2b, 0xbf, 0x87, 0xdd, 0xb4, + 0x5a, 0x9d, 0x2a, 0xa8, 0xcc, 0x4d, 0xcc, 0xd6, 0x0b, 0xa0, 0xa9, 0x56, + 0xa6, 0x63, 0xb5, 0x9e, 0xa5, 0x06, 0x3a, 0xe3, 0xab, 0xcc, 0x1d, 0x73, + 0xc5, 0x85, 0x8b, 0x13, 0x93, 0x1c, 0xb8, 0xe8, 0x25, 0xc9, 0xc3, 0x0a, + 0x92, 0x44, 0x4d, 0x41, 0xa4, 0xd4, 0x0f, 0x09, 0x36, 0xd3, 0x58, 0x0a, + 0x3d, 0xc3, 0xbc, 0xd7, 0xed, 0x34, 0x86, 0xf2, 0xad, 0x0f, 0xd6, 0xe7, + 0x2e, 0x28, 0x51, 0x89, 0x86, 0x6a, 0x5d, 0x3e, 0x3b, 0xe5, 0xa5, 0xb9, + 0x97, 0x5f, 0x6b, 0x2e, 0xcb, 0x55, 0x4b, 0x0b, 0xa5, 0xe3, 0xc9, 0xa6, + 0x0f, 0xdd, 0xbc, 0x6e, 0x57, 0x2c, 0xed, 0x0d, 0x63, 0x18, 0x44, 0xda, + 0x95, 0x5a, 0xb3, 0xc5, 0x52, 0x77, 0x00, 0x0d, 0xb6, 0xbb, 0x6d, 0xcf, + 0x0c, 0xfb, 0x85, 0x83, 0x7d, 0x05, 0xf7, 0x10, 0xcc, 0x0c, 0xa0, 0xe7, + 0x7f, 0x1c, 0xb0, 0x5c, 0x38, 0xfa, 0xa5, 0xfb, 0xfd, 0x92, 0x21, 0xab, + 0x59, 0xf8, 0x75, 0xc3, 0x61, 0x04, 0x9d, 0x12, 0x75, 0xe2, 0x8f, 0x61, + 0xf3, 0x77, 0x57, 0x0a, 0x41, 0x41, 0x92, 0x9d, 0xa1, 0xf8, 0xbb, 0x61, + 0x3e, 0x42, 0x53, 0x02, 0x7e, 0x37, 0x3a, 0x00, 0xf4, 0x3b, 0x2a, 0xd0, + 0x8f, 0x51, 0x00, 0x96, 0xdd, 0x3d, 0xe6, 0xd2, 0x08, 0x13, 0x33, 0x74, + 0xb7, 0x8e, 0x4e, 0x03, 0x4a, 0x8e, 0x40, 0xec, 0x07, 0x24, 0x04, 0xbc, + 0x41, 0x16, 0xe3, 0xad, 0x30, 0x34, 0x6e, 0x22, 0xa9, 0xc9, 0x57, 0x49, + 0x03, 0x36, 0xa8, 0x2d, 0x28, 0xd3, 0xd9, 0xef, 0x83, 0xb0, 0xf4, 0x09, + 0xf1, 0xfc, 0xea, 0x75, 0xc0, 0xb5, 0x88, 0xe5, 0xa9, 0x72, 0x9a, 0xf5, + 0xb5, 0x26, 0xeb, 0x8a, 0x00, 0xd1, 0xee, 0x80, 0x97, 0x23, 0x77, 0xf6, + 0xec, 0x22, 0xeb, 0xb9, 0x5f, 0x2b, 0x06, 0x53, 0x79, 0x22, 0xe4, 0x10, + 0x85, 0x73, 0x78, 0x53, 0x39, 0x93, 0x3e, 0xcc, 0xca, 0x69, 0xfd, 0xaf, + 0xcd, 0xbf, 0x4c, 0xc4, 0x7a, 0xa1, 0x43, 0x06, 0xd7, 0xf7, 0xb7, 0x18, + 0x42, 0x9f, 0xfa, 0x12, 0xc7, 0xde, 0xd7, 0x58, 0x65, 0xf1, 0x3b, 0xd3, + 0xa4, 0x14, 0x93, 0x69, 0xab, 0xcc, 0x0e, 0xe4, 0x94, 0xcd, 0xcc, 0xb5, + 0xb6, 0x3b, 0x3a, 0xe6, 0x62, 0x83, 0xf6, 0x91, 0x76, 0xc4, 0x0b, 0xe6, + 0x47, 0xf6, 0x8f, 0x06, 0x01, 0x8e, 0x6c, 0x8c, 0x81, 0xeb, 0x8b, 0x0e, + 0xc0, 0xa6, 0x2a, 0xe9, 0xa9, 0xcd, 0x1a, 0x43, 0x91, 0x35, 0x0f, 0xa0, + 0x3d, 0x20, 0x48, 0x21, 0x8b, 0x7b, 0x3b, 0x59, 0x49, 0x18, 0x5a, 0x6b, + 0xc6, 0xfe, 0xc9, 0xd7, 0xb3, 0x13, 0x5e, 0x56, 0x52, 0xfd, 0xf4, 0xcb, + 0x8b, 0xb4, 0x5e, 0xd1, 0x57, 0x09, 0xc9, 0x96, 0x51, 0x20, 0x16, 0x5c, + 0x8f, 0xdb, 0x8f, 0x21, 0xd8, 0x4b, 0xb1, 0x94, 0xe9, 0x17, 0x3d, 0x23, + 0xa3, 0xac, 0x3c, 0x42, 0x14, 0xc3, 0x0f, 0x29, 0x9e, 0x51, 0x3e, 0xae, + 0x33, 0xec, 0xe9, 0xe3, 0x0d, 0x0e, 0x3f, 0x39, 0x49, 0xa0, 0xbb, 0x9a, + 0x57, 0xa9, 0xb4, 0xb9, 0x2f, 0xf7, 0x3b, 0xf1, 0xd3, 0xc7, 0x39, 0x4f, + 0xb8, 0x4e, 0x93, 0x89, 0xa9, 0xa9, 0xf0, 0x32, 0x49, 0xa3, 0x9f, 0xa6, + 0x5f, 0x6e, 0xf2, 0x04, 0xdc, 0x4e, 0x57, 0x71, 0x01, 0x14, 0x32, 0x58, + 0x7b, 0xe3, 0x19, 0x21, 0xe4, 0x01, 0xf7, 0x3d, 0x4d, 0x4a, 0x25, 0x6a, + 0x1a, 0x37, 0xdc, 0xdd, 0x54, 0x88, 0xef, 0x74, 0xb8, 0x63, 0xdd, 0x5b, + 0x95, 0x92, 0x62, 0xae, 0xe5, 0x86, 0x50, 0x0f, 0x3e, 0x4d, 0x4c, 0xe1, + 0xe2, 0xda, 0x7f, 0xd1, 0x5a, 0xfe, 0x6d, 0x19, 0x1d, 0x9d, 0x16, 0x03, + 0x88, 0x41, 0x2a, 0x9d, 0x2a, 0xd9, 0x0e, 0xf3, 0xec, 0xee, 0xf5, 0x65, + 0x11, 0x0a, 0xde, 0x12, 0xa5, 0xaf, 0x93, 0xef, 0xc8, 0xea, 0xb1, 0xea, + 0x3d, 0x6b, 0x3f, 0x45, 0xa1, 0xc6, 0xc5, 0xc1, 0x31, 0x82, 0x74, 0x08, + 0xbd, 0x60, 0xca, 0x6c, 0xd8, 0x15, 0xd3, 0xdb, 0x2b, 0x4e, 0x22, 0x12, + 0x40, 0xe2, 0xed, 0xed, 0x4d, 0xc7, 0xcc, 0x8c, 0x00, 0x08, 0x0d, 0x0b, + 0xa3, 0xa4, 0xa2, 0x7a, 0x07, 0x11, 0xa5, 0x56, 0x4b, 0xd5, 0xa4, 0x90, + 0x28, 0x09, 0xab, 0x33, 0x1d, 0x2a, 0xb4, 0x9c, 0xca, 0xf5, 0x90, 0x9b, + 0xac, 0xa8, 0xd4, 0x6d, 0x76, 0x50, 0x07, 0x57, 0xda, 0x78, 0x34, 0x8b, + 0x1c, 0xf9, 0xc9, 0xbd, 0x8b, 0xcb, 0x6d, 0xa3, 0xf0, 0x24, 0x10, 0xae, + 0x7c, 0x2d, 0xfd, 0x9e, 0x84, 0x20, 0x86, 0xd1, 0xbb, 0x99, 0x58, 0x5c, + 0xa8, 0x49, 0xdf, 0xa4, 0xcb, 0xe5, 0x18, 0x5c, 0xf3, 0xfa, 0x12, 0xa8, + 0xbe, 0x46, 0xf5, 0x51, 0x22, 0xa0, 0xf5, 0x61, 0x20, 0xfd, 0x66, 0x95, + 0xaa, 0xb8, 0xb8, 0xf5, 0x8c, 0xed, 0x5b, 0x34, 0x1e, 0xd3, 0xf9, 0x41, + 0x51, 0x3c, 0xe8, 0x61, 0x3f, 0x4f, 0x5a, 0x59, 0xf9, 0x46, 0xd7, 0x3d, + 0xf0, 0x66, 0x41, 0xd3, 0xeb, 0xa4, 0x6e, 0x28, 0x7b, 0x90, 0xd0, 0xf4, + 0x3e, 0xa0, 0x67, 0xec, 0x60, 0xbe, 0x29, 0x0c, 0x68, 0x62, 0x37, 0x3c, + 0x59, 0xfa, 0xcb, 0xf4, 0x48, 0xd5, 0x51, 0x20, 0x96, 0xe3, 0xd7, 0x0b, + 0xfa, 0x7e, 0x09, 0xcb, 0x28, 0x46, 0x92, 0x12, 0x44, 0x05, 0xc2, 0x01, + 0xf2, 0xd5, 0x06, 0x6b, 0x00, 0x70, 0xc0, 0xd5, 0x4c, 0x39, 0x4d, 0xf6, + 0x8b, 0xd9, 0xa7, 0xe8, 0x02, 0x16, 0x8e, 0x51, 0x42, 0x3c, 0x4a, 0x6e, + 0xc8, 0x42, 0x69, 0xd8, 0x41, 0xac, 0x59, 0xbe, 0x44, 0x11, 0x45, 0x65, + 0x90, 0xf7, 0xa6, 0x1f, 0x9b, 0xdc, 0xaa, 0x52, 0x2e, 0x0a, 0xe1, 0x2c, + 0xa1, 0x16, 0xb1, 0x94, 0x88, 0x93, 0xdd, 0xaf, 0xd0, 0xc9, 0x2e, 0x19, + 0x06, 0x92, 0xde, 0xad, 0x7b, 0x92, 0x8f, 0x5b, 0xb8, 0x36, 0x8a, 0x78, + 0xbe, 0x05, 0x2c, 0x71, 0x01, 0x7f, 0xac, 0xaf, 0xe6, 0x24, 0x79, 0xd3, + 0xd8, 0xeb, 0xf4, 0x53, 0x52, 0x31, 0xf6, 0x0f, 0x90, 0x29, 0x6a, 0xa2, + 0x39, 0x88, 0x6a, 0x1e, 0xf4, 0x4b, 0x61, 0xf4, 0x76, 0x27, 0x17, 0x17, + 0x12, 0xa6, 0x0e, 0x3d, 0xde, 0x1d, 0x04, 0x4d, 0x6d, 0x04, 0xac, 0x7e, + 0xb4, 0xf5, 0x41, 0x72, 0x2e, 0x81, 0x50, 0x94, 0xb1, 0x80, 0xf5, 0xf0, + 0x85, 0xee, 0x33, 0xc9, 0x6f, 0x32, 0x9f, 0x0d, 0x72, 0xae, 0x00, 0x93, + 0xd9, 0xdd, 0x31, 0x86, 0x3c, 0x69, 0x69, 0x7a, 0xea, 0xf4, 0xb8, 0x2d, + 0x77, 0x93, 0x05, 0x2d, 0x5e, 0x7c, 0xd8, 0x69, 0xd5, 0x66, 0xe2, 0x29, + 0xd4, 0x56, 0xf3, 0xf4, 0x70, 0x65, 0xea, 0x04, 0x6b, 0xcd, 0x28, 0xfc, + 0x0d, 0xd6, 0x71, 0x4d, 0x4c, 0x3b, 0x98, 0x44, 0x58, 0x31, 0x5b, 0xf9, + 0x00, 0xb8, 0xd7, 0x46, 0x3f, 0xfa, 0xee, 0x5a, 0xb8, 0xf7, 0x58, 0x53, + 0xa0, 0x76, 0x75, 0xdd, 0xd3, 0xdc, 0x1e, 0x4d, 0x68, 0xe8, 0x6b, 0x54, + 0xe9, 0x84, 0x45, 0x44, 0x54, 0xd0, 0x67, 0xa7, 0xee, 0x64, 0x7f, 0x14, + 0x16, 0x26, 0xcb, 0xc8, 0xc8, 0xf0, 0xd8, 0x39, 0xd5, 0xe1, 0x1a, 0xe8, + 0x6d, 0x55, 0x2a, 0x70, 0x1e, 0x8f, 0xdd, 0x3c, 0x73, 0x74, 0x78, 0x03, + 0x76, 0x27, 0x24, 0xe6, 0x38, 0xf2, 0x0c, 0x6a, 0x0d, 0xef, 0x67, 0x1f, + 0x5b, 0x8c, 0xe0, 0x24, 0x4d, 0xe5, 0x6f, 0xce, 0xf6, 0xd3, 0x52, 0x81, + 0x9c, 0xed, 0x8d, 0xb7, 0x9b, 0x9f, 0x60, 0x54, 0xd3, 0x46, 0x77, 0xde, + 0xbc, 0x77, 0xd9, 0x62, 0x48, 0xe6, 0x55, 0xab, 0x6b, 0x23, 0xc8, 0x19, + 0x3e, 0x33, 0xf5, 0xfd, 0xd3, 0xbe, 0x4a, 0xb8, 0xd2, 0xcc, 0xbb, 0x6a, + 0x97, 0x42, 0x0d, 0xa2, 0x96, 0xd1, 0xea, 0x7e, 0x01, 0x00, 0x44, 0x29, + 0x11, 0xbd, 0xf6, 0x07, 0xa4, 0x59, 0x6f, 0x9b, 0x36, 0x00, 0x46, 0x59, + 0xff, 0x34, 0x92, 0x59, 0xf2, 0xcd, 0x11, 0xb0, 0x0d, 0x1e, 0xce, 0x89, + 0x4f, 0xf8, 0x9d, 0x7a, 0xad, 0x0d, 0xfd, 0xfc, 0x04, 0xa1, 0x65, 0xb1, + 0x7e, 0x90, 0xf9, 0x20, 0x46, 0xd1, 0x5b, 0x54, 0xb0, 0x18, 0x76, 0x91, + 0xdc, 0x6d, 0x06, 0x76, 0xdb, 0x0b, 0xf0, 0xb3, 0x7f, 0x78, 0xcb, 0x76, + 0x67, 0x09, 0x47, 0x3f, 0x50, 0x34, 0x0c, 0xd5, 0x77, 0xca, 0x99, 0x86, + 0x9d, 0xed, 0xeb, 0x23, 0xb7, 0x52, 0xd7, 0xba, 0xe7, 0x52, 0x88, 0xab, + 0x84, 0x6d, 0xdb, 0x55, 0xb4, 0x43, 0x46, 0xe9, 0xa6, 0x53, 0xaf, 0xc4, + 0xce, 0x35, 0x96, 0xa7, 0x51, 0x27, 0x7b, 0x33, 0x3b, 0xe4, 0x27, 0x50, + 0x58, 0xe8, 0x7e, 0xf9, 0x1a, 0xd1, 0xfe, 0x7b, 0xe5, 0xcf, 0xe6, 0xcf, + 0xf1, 0xef, 0x97, 0x20, 0xea, 0x2c, 0x0f, 0x52, 0x04, 0xe5, 0xdc, 0x06, + 0x43, 0x5f, 0x9f, 0x36, 0xa6, 0x0c, 0xcd, 0x98, 0x05, 0xce, 0x48, 0x04, + 0x78, 0x9b, 0xf3, 0xcd, 0xa5, 0xdc, 0xbf, 0x02, 0x2c, 0xc2, 0xa0, 0x79, + 0xcc, 0x93, 0xd5, 0x46, 0x5b, 0xaf, 0xeb, 0x19, 0x69, 0xe8, 0x4b, 0xff, + 0xe7, 0xc7, 0xe3, 0x9a, 0xe1, 0x29, 0x16, 0x25, 0x09, 0x8b, 0x7a, 0xc2, + 0x52, 0xc5, 0x9c, 0xde, 0x0e, 0xef, 0xab, 0xf3, 0xf3, 0x3e, 0x74, 0x60, + 0x5c, 0x7c, 0x74, 0x6c, 0x6f, 0xf3, 0x9b, 0x37, 0xe6, 0x47, 0x84, 0xdb, + 0x7c, 0x33, 0x03, 0xd8, 0xec, 0xac, 0x4c, 0x3c, 0x3c, 0x87, 0x3b, 0xbd, + 0x0b, 0x00, 0xb9, 0xa4, 0x88, 0x73, 0x7f, 0xa4, 0x38, 0xe6, 0x5d, 0x26, + 0x9d, 0xc5, 0x78, 0xa5, 0x20, 0xb7, 0xf5, 0x89, 0x51, 0x07, 0xff, 0x7e, + 0x00, 0xe2, 0xb5, 0x5c, 0x94, 0x17, 0xe2, 0x3e, 0x09, 0x84, 0x62, 0x62, + 0x97, 0x6b, 0xd6, 0xeb, 0x81, 0x03, 0x6f, 0x13, 0x65, 0xbc, 0xbc, 0x2e, + 0xad, 0x9a, 0x73, 0x39, 0x3e, 0xef, 0x22, 0x77, 0xe9, 0x74, 0x61, 0xfa, + 0xa2, 0xe5, 0x04, 0xab, 0xbb, 0x31, 0x2f, 0x55, 0x28, 0xd3, 0x61, 0x60, + 0x62, 0x7e, 0xff, 0xf3, 0x87, 0x3d, 0x25, 0x35, 0x75, 0xe5, 0x34, 0x1a, + 0x19, 0x7d, 0x00, 0x74, 0x97, 0xf7, 0x45, 0xbc, 0x7e, 0xd0, 0x21, 0x76, + 0x64, 0xa9, 0xa5, 0x4d, 0x9c, 0x45, 0x49, 0x92, 0x89, 0x2a, 0xa8, 0x81, + 0x4a, 0xf3, 0x8c, 0x72, 0xe1, 0x0b, 0xc4, 0x5d, 0x64, 0x24, 0x24, 0x9a, + 0x1d, 0x01, 0xea, 0xd6, 0xbb, 0x75, 0x10, 0xcf, 0xe8, 0x09, 0xc4, 0xaf, + 0x29, 0xa4, 0x65, 0xee, 0x37, 0x55, 0x61, 0xb6, 0xa4, 0x98, 0x90, 0x64, + 0xc7, 0x87, 0x83, 0x61, 0x11, 0xe4, 0x86, 0x47, 0x5f, 0xdf, 0x79, 0x35, + 0xd8, 0x27, 0x05, 0x72, 0x0e, 0x3d, 0x43, 0x26, 0xba, 0x44, 0x2e, 0x18, + 0x8f, 0x77, 0x31, 0x69, 0xfb, 0x4b, 0xf2, 0x9b, 0x84, 0x81, 0x41, 0xae, + 0x3e, 0xfb, 0x12, 0x02, 0xbc, 0xc9, 0x63, 0x71, 0xa2, 0x56, 0xd3, 0x16, + 0x8d, 0xec, 0xde, 0x02, 0x06, 0xe6, 0x2f, 0x77, 0x3e, 0x66, 0x44, 0xc1, + 0x35, 0x08, 0x98, 0x92, 0xd0, 0x1b, 0x4a, 0x64, 0xa7, 0xa4, 0x96, 0x1c, + 0xe0, 0x44, 0xfd, 0x5a, 0xe2, 0x65, 0x69, 0x45, 0x49, 0x05, 0x83, 0x20, + 0xb9, 0x10, 0x6e, 0x90, 0xc0, 0xc7, 0xb3, 0x53, 0x72, 0xf0, 0x20, 0xa2, + 0x5b, 0xab, 0xc9, 0x87, 0x38, 0xee, 0x93, 0x7e, 0x03, 0xb1, 0x2a, 0xe2, + 0xbb, 0x8d, 0xe7, 0xee, 0x1f, 0xac, 0xbb, 0xb7, 0x3d, 0x37, 0x3e, 0x72, + 0xed, 0xce, 0xf2, 0x70, 0x60, 0x42, 0x1e, 0x44, 0xb6, 0x6f, 0x98, 0xc3, + 0x2c, 0xf4, 0xdf, 0xd5, 0x71, 0x30, 0x09, 0xf2, 0xa5, 0x82, 0xa4, 0xec, + 0x35, 0xbd, 0x0e, 0x9b, 0x5e, 0xd7, 0xcf, 0x57, 0x74, 0x5d, 0x59, 0x5d, + 0x8c, 0x94, 0x42, 0xe1, 0x34, 0x03, 0x33, 0xb2, 0x44, 0xe4, 0xe4, 0xa6, + 0x06, 0x47, 0xea, 0xd3, 0xb2, 0x07, 0xf9, 0x34, 0x59, 0xe0, 0x47, 0xf5, + 0x36, 0xe3, 0x28, 0x17, 0xc4, 0xc3, 0xcc, 0x23, 0xe4, 0x0a, 0xbd, 0xcc, + 0x3f, 0x9b, 0xae, 0xfa, 0xf2, 0xb2, 0xe4, 0x28, 0x7b, 0x3f, 0x8f, 0xed, + 0x76, 0x17, 0x48, 0x97, 0x72, 0x1f, 0x2c, 0x75, 0x76, 0xea, 0x15, 0x60, + 0x8a, 0x38, 0x71, 0x71, 0xe0, 0x57, 0x72, 0x9f, 0x86, 0x51, 0xb0, 0x0a, + 0xbe, 0xdd, 0x7d, 0x3e, 0x98, 0xad, 0xa6, 0x31, 0xf0, 0xba, 0x93, 0x83, + 0x5e, 0x8a, 0x01, 0x93, 0xcc, 0x4c, 0x7d, 0x64, 0x2b, 0x53, 0xa7, 0x87, + 0xde, 0x1a, 0x54, 0x1d, 0x42, 0x87, 0xd9, 0x07, 0x98, 0x06, 0x51, 0x3b, + 0xe3, 0xa4, 0xa6, 0x80, 0xfc, 0x6c, 0xf8, 0xd5, 0xe8, 0x69, 0xda, 0x3c, + 0xed, 0x50, 0xc3, 0xa2, 0x77, 0x1d, 0x8b, 0x6d, 0x0a, 0x74, 0x96, 0x0c, + 0xfd, 0x52, 0x46, 0x11, 0x43, 0x16, 0x32, 0x8f, 0xb7, 0xad, 0xfc, 0x50, + 0x84, 0x30, 0x68, 0xd4, 0x55, 0xca, 0xf9, 0xb9, 0xeb, 0xb4, 0x98, 0x69, + 0xdf, 0xd1, 0xb6, 0xfb, 0xc6, 0x6f, 0x17, 0xf4, 0xdc, 0x83, 0x8b, 0xd2, + 0xa6, 0xa9, 0xba, 0x12, 0x21, 0x83, 0x92, 0xff, 0x4c, 0x36, 0x0c, 0xfd, + 0xf4, 0xda, 0x88, 0x01, 0x59, 0xc3, 0xf3, 0xc7, 0xb9, 0x39, 0x36, 0x67, + 0x79, 0xef, 0x76, 0x3b, 0x19, 0x10, 0x06, 0xdc, 0x63, 0xea, 0xc2, 0xb4, + 0x7f, 0xb3, 0x0d, 0xc3, 0x5e, 0x60, 0xe7, 0xa8, 0xb1, 0x9a, 0xf9, 0xb4, + 0xcd, 0x7b, 0xe9, 0x9f, 0x3f, 0xc1, 0xf9, 0xbd, 0xf8, 0xee, 0xa2, 0x86, + 0x4c, 0x32, 0xc3, 0xed, 0x77, 0x28, 0xff, 0xbb, 0x0b, 0x90, 0xca, 0xf8, + 0xb3, 0x58, 0x5e, 0x0c, 0xf1, 0x61, 0xda, 0xb9, 0x03, 0x22, 0x13, 0xf7, + 0x37, 0x5e, 0xb3, 0x2d, 0xba, 0xb0, 0x9b, 0x19, 0xe8, 0x3f, 0x0f, 0x8c, + 0xa7, 0xed, 0xef, 0xcc, 0xa6, 0xca, 0x0b, 0xb2, 0x9b, 0x7f, 0x00, 0x93, + 0xf9, 0x57, 0xda, 0x93, 0xd3, 0xb8, 0x6e, 0x4e, 0xd7, 0x29, 0xb8, 0x96, + 0xb2, 0x89, 0x29, 0xff, 0x8c, 0x34, 0x29, 0x8f, 0x2e, 0x92, 0x51, 0x50, + 0x16, 0xff, 0xc4, 0x33, 0xff, 0x7b, 0x25, 0x85, 0x26, 0x88, 0x1e, 0xe8, + 0xfc, 0x0c, 0xda, 0xfd, 0xf0, 0xdc, 0x71, 0x81, 0xce, 0x27, 0x4e, 0x25, + 0x2c, 0x6f, 0x68, 0x21, 0x21, 0x3e, 0xa7, 0x25, 0xf8, 0x34, 0x4c, 0x2d, + 0xc8, 0x67, 0xfa, 0x8e, 0xe9, 0xe5, 0x52, 0x2c, 0x07, 0x48, 0x23, 0x7a, + 0x5a, 0x2b, 0xa8, 0x9c, 0xf4, 0xe1, 0x1b, 0xc2, 0x17, 0x9b, 0xf7, 0x19, + 0xe2, 0x97, 0x84, 0x9c, 0x9f, 0xe3, 0xd6, 0x94, 0x9d, 0x2f, 0x30, 0x43, + 0xc4, 0x31, 0x69, 0x5c, 0x0c, 0xb8, 0x07, 0x9d, 0x37, 0x23, 0xeb, 0xd3, + 0x58, 0x1d, 0xb4, 0xc8, 0x33, 0x3f, 0x48, 0xac, 0xd1, 0xaa, 0x11, 0x87, + 0x3a, 0x7f, 0x79, 0xca, 0xf7, 0x1d, 0x5a, 0x6c, 0x90, 0x98, 0x95, 0x2e, + 0x4f, 0x41, 0x3e, 0x11, 0xc9, 0x0c, 0xfd, 0xbd, 0x16, 0x2c, 0x5b, 0x34, + 0x3a, 0x3b, 0x3c, 0x6c, 0x5d, 0x43, 0xfc, 0x21, 0xd2, 0x6d, 0xac, 0x13, + 0xed, 0x00, 0x39, 0x67, 0x4d, 0xed, 0xe9, 0x56, 0xc9, 0x1f, 0xa1, 0xac, + 0x86, 0x37, 0x2e, 0x8d, 0x30, 0xc6, 0xeb, 0x72, 0x21, 0xfe, 0x9b, 0x72, + 0x71, 0xf2, 0x47, 0x46, 0xf1, 0xaf, 0xb0, 0xb8, 0x24, 0x66, 0x9b, 0x23, + 0xdf, 0x30, 0xde, 0xdd, 0xe1, 0xe0, 0xf8, 0x29, 0xd8, 0x4e, 0x1f, 0x47, + 0x60, 0xf1, 0xb7, 0x96, 0x73, 0x58, 0x6e, 0xb0, 0xb2, 0xe3, 0x35, 0x0d, + 0x2f, 0x74, 0x35, 0x5c, 0x33, 0xfa, 0xdd, 0xf6, 0xf9, 0x28, 0xfd, 0x90, + 0x40, 0xbc, 0xf8, 0x9c, 0xa9, 0xef, 0x22, 0xbd, 0x85, 0x42, 0x57, 0x90, + 0x6c, 0xf3, 0xad, 0x32, 0x8b, 0x19, 0x27, 0x74, 0x7a, 0xa7, 0xfa, 0xb6, + 0x6a, 0xa3, 0x01, 0x7f, 0x48, 0xb1, 0xd4, 0x8b, 0x9f, 0x5a, 0x3c, 0x22, + 0x7e, 0x6b, 0xad, 0x38, 0x51, 0x00, 0xc1, 0x50, 0x14, 0x29, 0x47, 0x2d, + 0x7a, 0x24, 0xc5, 0xca, 0x9c, 0x11, 0x8c, 0x34, 0xa8, 0xa6, 0x58, 0x02, + 0x92, 0x90, 0xe9, 0x8d, 0xba, 0x11, 0xd8, 0x45, 0x8c, 0xc6, 0x00, 0xc1, + 0xaa, 0x55, 0xe0, 0xf9, 0xee, 0xc6, 0xf5, 0xe0, 0x43, 0x4c, 0xb3, 0x40, + 0x1b, 0x35, 0xf2, 0xfe, 0x7b, 0xd9, 0x5b, 0xeb, 0x6a, 0xf3, 0xd3, 0x96, + 0x8c, 0xd9, 0x3e, 0xae, 0x0f, 0xb4, 0x17, 0x74, 0x8c, 0x81, 0x6c, 0x4a, + 0x97, 0xa1, 0xff, 0x06, 0x22, 0xfa, 0x56, 0x4e, 0xd4, 0x09, 0x80, 0xa3, + 0xe6, 0x8f, 0xcb, 0x1a, 0xc7, 0xf3, 0x7b, 0xed, 0x73, 0x74, 0x09, 0x95, + 0x40, 0xb4, 0xde, 0x92, 0xa8, 0xe3, 0x95, 0x00, 0x13, 0xf8, 0x41, 0xf2, + 0xbc, 0xca, 0x47, 0x8b, 0x2b, 0x99, 0x22, 0xa9, 0xb9, 0x13, 0x24, 0x51, + 0x27, 0x1b, 0xc9, 0x46, 0x07, 0x60, 0x80, 0x5e, 0xd7, 0xcf, 0x8f, 0xd2, + 0x5a, 0xa1, 0x09, 0x08, 0xa1, 0x3f, 0xdb, 0x16, 0xd1, 0x65, 0x0f, 0x8a, + 0x07, 0xe5, 0x7f, 0xa1, 0xfc, 0x48, 0x19, 0x5d, 0x36, 0x8f, 0xdb, 0x29, + 0xa4, 0x33, 0x7e, 0x12, 0x2e, 0x8d, 0xf6, 0x14, 0x47, 0xac, 0xc3, 0xae, + 0x40, 0x6d, 0x00, 0x5a, 0xc8, 0x63, 0x33, 0xa9, 0xd2, 0x09, 0x87, 0x61, + 0xf1, 0x97, 0xe3, 0x0e, 0xf6, 0xee, 0xb3, 0xfe, 0x72, 0xb7, 0xc9, 0x68, + 0x78, 0x88, 0xef, 0xc3, 0xa0, 0x91, 0x89, 0x4b, 0x40, 0xa4, 0x44, 0xc5, + 0xd9, 0x0f, 0x8f, 0x24, 0x9a, 0x30, 0xca, 0x3c, 0x34, 0x90, 0x4e, 0x99, + 0x96, 0xa9, 0xd2, 0x62, 0xb4, 0x94, 0x83, 0xb0, 0x94, 0x7a, 0x18, 0x0b, + 0x9e, 0xe3, 0x97, 0xb5, 0x12, 0x37, 0x3b, 0xa0, 0xaf, 0x7c, 0x75, 0x2d, + 0xa4, 0x1d, 0xd6, 0x98, 0xed, 0xe6, 0x2b, 0x47, 0xf2, 0xda, 0x37, 0x4e, + 0x37, 0x68, 0xbb, 0x0c, 0xf9, 0x91, 0x2c, 0xc0, 0x29, 0x4f, 0xdc, 0x8e, + 0x21, 0xf3, 0x26, 0xe2, 0xb7, 0xe2, 0x4a, 0x37, 0xf1, 0xaf, 0xee, 0xf0, + 0x01, 0x3e, 0x20, 0x09, 0xcb, 0xd6, 0x10, 0xab, 0x73, 0xc8, 0xb4, 0xf8, + 0xa3, 0x7c, 0xf0, 0x94, 0x77, 0x35, 0xc9, 0x5a, 0xbd, 0xf8, 0x60, 0x4b, + 0xa7, 0x4a, 0x47, 0x70, 0xd0, 0x29, 0x8b, 0x8d, 0x8d, 0x11, 0xd1, 0xc0, + 0x9d, 0x3a, 0x60, 0xba, 0xff, 0xa6, 0x25, 0x6d, 0x5d, 0x42, 0xaf, 0x3e, + 0x1e, 0x1f, 0x57, 0x14, 0x48, 0x26, 0x97, 0xf4, 0x91, 0x00, 0xb2, 0x50, + 0x4e, 0x34, 0x1f, 0x9b, 0x67, 0xf1, 0x76, 0x82, 0xca, 0xb5, 0x9a, 0x8c, + 0xfc, 0x20, 0xb4, 0x53, 0xc5, 0x12, 0x2f, 0xfa, 0x52, 0x9d, 0x62, 0xda, + 0xa1, 0x73, 0x75, 0x14, 0xb5, 0xbd, 0x80, 0xa5, 0x68, 0x50, 0x26, 0x14, + 0xc3, 0x37, 0xa9, 0x9f, 0x14, 0xbc, 0xc5, 0x76, 0x70, 0x73, 0x88, 0xd0, + 0x0a, 0xba, 0xa0, 0x49, 0x99, 0x8e, 0x24, 0xd6, 0xfb, 0x6c, 0xcc, 0x78, + 0x7e, 0x3c, 0xfa, 0x11, 0x7e, 0x80, 0xff, 0x84, 0xcf, 0x4f, 0xb6, 0x3a, + 0x08, 0x91, 0xd2, 0xa0, 0xa2, 0x58, 0x2d, 0x5e, 0xc5, 0x7f, 0xf7, 0x99, + 0x29, 0x1d, 0xf6, 0x1d, 0xd1, 0x4c, 0x31, 0x31, 0x4f, 0x7e, 0xa8, 0xe2, + 0x9a, 0x78, 0x25, 0xe9, 0x2d, 0x19, 0x86, 0xd9, 0x52, 0x81, 0xf9, 0xcd, + 0x9e, 0xff, 0xd6, 0x5a, 0xf9, 0xb5, 0x00, 0x65, 0x7f, 0x7c, 0xd8, 0x0f, + 0x9b, 0x19, 0x3a, 0xfe, 0x8e, 0xd9, 0x08, 0x50, 0xe1, 0x8c, 0xd7, 0x30, + 0xa3, 0xae, 0xa8, 0x70, 0x28, 0x16, 0xbf, 0x33, 0x4a, 0x8e, 0x83, 0x3a, + 0x92, 0xa9, 0x58, 0x8d, 0x3a, 0x99, 0x80, 0x9b, 0x20, 0xa1, 0xa5, 0x6a, + 0xf5, 0x28, 0x2e, 0x16, 0x65, 0xbf, 0x1c, 0x3c, 0xbc, 0x9a, 0x81, 0x0b, + 0xb3, 0x0a, 0x36, 0x22, 0x4f, 0x01, 0xa4, 0x3f, 0x5a, 0xde, 0xfb, 0xef, + 0x8d, 0xa2, 0xd3, 0xbb, 0xa3, 0xa6, 0xed, 0x68, 0x2d, 0x27, 0x2d, 0xb2, + 0x88, 0x94, 0x81, 0xdf, 0x24, 0x86, 0x49, 0xbf, 0xd7, 0x40, 0x07, 0xfb, + 0xd5, 0xe0, 0x56, 0x20, 0x56, 0xe5, 0x70, 0x21, 0xbf, 0x5b, 0x17, 0xdb, + 0x8e, 0xf6, 0xa5, 0x10, 0xba, 0x1b, 0x2f, 0x2b, 0x4f, 0x2b, 0x57, 0xc2, + 0x64, 0xeb, 0x95, 0xfa, 0x3e, 0x89, 0x08, 0xda, 0x41, 0x14, 0xdb, 0x84, + 0x63, 0x30, 0x86, 0x96, 0x72, 0x5d, 0x4e, 0x6e, 0x46, 0x34, 0x44, 0x30, + 0xb9, 0x84, 0x43, 0x9c, 0x90, 0x3d, 0xf8, 0x2f, 0xbd, 0xfd, 0xe7, 0x32, + 0xf1, 0xec, 0x2c, 0x88, 0x03, 0x39, 0x98, 0xb3, 0x93, 0x36, 0xbf, 0xeb, + 0x21, 0xd7, 0x20, 0x7b, 0x72, 0x3e, 0x45, 0x6b, 0xed, 0xa5, 0x0c, 0xf5, + 0x2a, 0x00, 0xe7, 0xe8, 0x68, 0xae, 0x26, 0xb1, 0x9b, 0xa1, 0xf4, 0x0f, + 0x41, 0x5b, 0xe0, 0x63, 0xce, 0xdc, 0x75, 0x07, 0x63, 0xf8, 0x14, 0x9a, + 0x3c, 0xfd, 0xbd, 0x30, 0xa3, 0x87, 0x97, 0x43, 0xac, 0xfb, 0x56, 0xa9, + 0xe6, 0xf2, 0x63, 0x2b, 0x99, 0xae, 0x00, 0xbb, 0x79, 0x6c, 0x6a, 0xd3, + 0x0a, 0x41, 0x7c, 0x5f, 0xc3, 0x2e, 0xed, 0xe0, 0x9a, 0xd7, 0x8d, 0x4a, + 0x1b, 0xba, 0x13, 0x6d, 0x40, 0xfd, 0xa9, 0xbb, 0xec, 0xd2, 0x22, 0x58, + 0xcf, 0xf9, 0x9e, 0x08, 0xe2, 0x3e, 0x06, 0x70, 0xef, 0x3f, 0xd9, 0xc1, + 0xcd, 0x37, 0xed, 0xd2, 0x45, 0x5a, 0xaa, 0x38, 0xb8, 0xf1, 0x52, 0xf6, + 0x3b, 0xd6, 0x05, 0x6d, 0x74, 0xe2, 0x33, 0xec, 0xc6, 0xf5, 0x42, 0x9d, + 0xf8, 0x46, 0xbc, 0x14, 0x68, 0x8a, 0x19, 0x1a, 0x74, 0x83, 0x0b, 0x14, + 0x78, 0x13, 0x14, 0x93, 0xb4, 0x40, 0xa4, 0xdc, 0xca, 0xfe, 0x78, 0x63, + 0xa3, 0x51, 0x82, 0xe9, 0xfa, 0xaf, 0x5c, 0xf5, 0xea, 0x2c, 0x85, 0x89, + 0x82, 0x5c, 0x1c, 0x29, 0x67, 0x9e, 0x78, 0x12, 0x36, 0x4d, 0xb3, 0x43, + 0x51, 0xa6, 0x3d, 0x1c, 0xc5, 0x9a, 0xf3, 0x2e, 0x0c, 0x23, 0x70, 0x88, + 0xe0, 0x4b, 0xf5, 0x0b, 0x93, 0x67, 0xfa, 0xc4, 0xe1, 0x84, 0x39, 0xf2, + 0x50, 0x29, 0xb4, 0x2f, 0xa9, 0xa2, 0x48, 0x20, 0x4c, 0xd9, 0x15, 0x4c, + 0x10, 0xac, 0xd7, 0xd1, 0x4d, 0xfc, 0x37, 0x15, 0x1d, 0x5a, 0xe8, 0xce, + 0x35, 0x1f, 0x6e, 0x6a, 0x4a, 0xaf, 0x0d, 0xee, 0xe9, 0x20, 0x2f, 0x0f, + 0x57, 0xf2, 0x67, 0x92, 0xbc, 0xff, 0x7a, 0x2b, 0x62, 0x9b, 0x19, 0x4f, + 0x9f, 0x6d, 0xb2, 0x50, 0xd0, 0xd4, 0x41, 0xf0, 0x28, 0xe2, 0xc1, 0x10, + 0xff, 0x3f, 0x9a, 0xbe, 0x3a, 0x20, 0xaa, 0xe7, 0x7b, 0x7b, 0x01, 0x69, + 0x84, 0xa5, 0x3b, 0x56, 0x52, 0xa5, 0xa5, 0xbb, 0xa4, 0x45, 0x96, 0x92, + 0x06, 0x59, 0x5a, 0xa4, 0x96, 0x96, 0x12, 0x97, 0x90, 0x0e, 0x49, 0x97, + 0x06, 0x91, 0x2e, 0xe9, 0xee, 0x92, 0x12, 0x90, 0x6e, 0x49, 0xe9, 0x96, + 0x7c, 0xef, 0x7e, 0xbe, 0xbf, 0x97, 0x7f, 0x77, 0x38, 0x73, 0xe6, 0x9c, + 0xe7, 0x3c, 0xf3, 0x9c, 0xb9, 0xbb, 0x77, 0x7c, 0x19, 0x60, 0x23, 0x6d, + 0x98, 0x64, 0xe1, 0x4c, 0x45, 0x14, 0x5b, 0x58, 0x00, 0x0c, 0x5b, 0x2c, + 0xd4, 0xe1, 0x3f, 0xd6, 0x6a, 0x14, 0x4b, 0xe5, 0x34, 0x35, 0x03, 0x51, + 0x87, 0x4c, 0x96, 0x14, 0x14, 0x24, 0x04, 0xf9, 0x5a, 0x6f, 0x85, 0xd9, + 0xc2, 0x43, 0xb4, 0x52, 0x3b, 0x8f, 0x9f, 0xa2, 0x06, 0xad, 0x19, 0x7b, + 0x67, 0xad, 0xb9, 0x57, 0x6a, 0xc4, 0xec, 0x19, 0xef, 0x76, 0xc9, 0x84, + 0xb5, 0x45, 0xe0, 0xe0, 0xbb, 0x50, 0xc5, 0xd9, 0x6a, 0x21, 0x69, 0x51, + 0xfe, 0x3c, 0xe3, 0xf8, 0xbe, 0x4f, 0x2d, 0xf3, 0xb6, 0x74, 0xa6, 0x35, + 0x2d, 0xf5, 0x39, 0xea, 0x80, 0x94, 0x67, 0xac, 0xc1, 0x44, 0x2d, 0x94, + 0x38, 0xce, 0xb1, 0xa1, 0x09, 0x05, 0xd3, 0xf2, 0xb3, 0xeb, 0x3b, 0xef, + 0xc0, 0x35, 0xb9, 0x9e, 0x8b, 0xfc, 0xe7, 0xa9, 0xae, 0x21, 0xf2, 0x38, + 0xc7, 0xe8, 0xe3, 0xc4, 0xd9, 0x1e, 0xf3, 0x41, 0x60, 0x24, 0xcf, 0xff, + 0x0a, 0xeb, 0x18, 0x94, 0x5d, 0xbf, 0x36, 0xb5, 0xd4, 0x55, 0xb0, 0x41, + 0x80, 0x00, 0xaf, 0x05, 0x8b, 0xd8, 0x34, 0xfd, 0xf9, 0x5f, 0xf1, 0x67, + 0xc4, 0xea, 0x1f, 0xaf, 0x6d, 0xef, 0xe0, 0x73, 0xbc, 0xd0, 0x84, 0xb3, + 0xca, 0xdd, 0x1a, 0xa8, 0x14, 0x76, 0x38, 0x7e, 0x85, 0xfb, 0x51, 0xa6, + 0xca, 0xa1, 0x1c, 0xfb, 0x8c, 0xcd, 0x6b, 0xd2, 0xf3, 0x3c, 0x77, 0x20, + 0xf2, 0x4e, 0x69, 0xb4, 0x9f, 0x9a, 0x00, 0xa2, 0x60, 0x2d, 0xd6, 0xa2, + 0x2d, 0x89, 0xb7, 0xfb, 0x7b, 0xed, 0xbf, 0xa5, 0x69, 0x73, 0xc8, 0x8d, + 0xe8, 0x2e, 0x99, 0xb6, 0xdd, 0xc9, 0xe8, 0x86, 0x92, 0xc8, 0xdd, 0xca, + 0x28, 0x3b, 0xc7, 0x2e, 0xd6, 0x6a, 0x51, 0xaf, 0x89, 0xec, 0xa7, 0x4f, + 0xa2, 0xb3, 0xba, 0xad, 0xa1, 0x15, 0x45, 0x24, 0xd6, 0x5d, 0xd0, 0x49, + 0x05, 0xff, 0x38, 0x73, 0x68, 0x08, 0x82, 0x20, 0xfa, 0x39, 0x75, 0x68, + 0x6d, 0xeb, 0x86, 0x1b, 0xdc, 0xb2, 0xc3, 0xe5, 0x55, 0x1e, 0xa3, 0x56, + 0xc6, 0xcd, 0x92, 0xb7, 0x0c, 0x95, 0x79, 0xdb, 0xd4, 0xc7, 0xa6, 0x42, + 0x37, 0x7f, 0x41, 0x9f, 0xf0, 0x02, 0x60, 0x1e, 0xca, 0x38, 0x16, 0x28, + 0xb3, 0x27, 0x41, 0x6b, 0x20, 0xc0, 0x07, 0x9e, 0x2f, 0x5f, 0x16, 0xab, + 0xa1, 0xe5, 0x2f, 0xfa, 0xd4, 0x00, 0xfd, 0xe0, 0x47, 0x85, 0xc5, 0x69, + 0x9c, 0x63, 0x35, 0xb6, 0xea, 0x29, 0xc0, 0x45, 0x58, 0xe6, 0xef, 0xd2, + 0xe5, 0x6c, 0x5f, 0x1d, 0xa5, 0x33, 0x4a, 0x65, 0x09, 0x05, 0x11, 0x63, + 0xef, 0xbf, 0x72, 0xbb, 0x82, 0x74, 0x92, 0x2f, 0x3d, 0x67, 0x71, 0x8e, + 0x95, 0x68, 0x6a, 0x60, 0x37, 0xf0, 0xb2, 0x91, 0xfe, 0x19, 0x65, 0xf7, + 0x6c, 0x14, 0x97, 0x1e, 0x83, 0x33, 0xf6, 0x44, 0xaa, 0x4e, 0x47, 0xd7, + 0x5d, 0x1f, 0xc9, 0xe1, 0xc4, 0x19, 0xc8, 0x56, 0xc2, 0x76, 0x3c, 0x56, + 0x9b, 0x3b, 0x2a, 0x62, 0x0c, 0xf9, 0x7e, 0x13, 0x03, 0x8e, 0x12, 0x07, + 0x65, 0x0d, 0xbb, 0xd2, 0xcd, 0xfb, 0x1d, 0xb1, 0x28, 0xa8, 0xc4, 0x33, + 0xd3, 0xc9, 0x85, 0x45, 0x12, 0x28, 0xf6, 0x19, 0x92, 0x2d, 0xec, 0x9e, + 0xc8, 0x68, 0x31, 0x03, 0x61, 0x50, 0xe2, 0xa5, 0x70, 0xed, 0x77, 0xd9, + 0x33, 0xd4, 0x63, 0xf0, 0x60, 0x14, 0x79, 0xaa, 0x04, 0x64, 0x80, 0x7a, + 0x83, 0x32, 0xa9, 0x9f, 0x3e, 0xe8, 0x75, 0x0e, 0x42, 0x43, 0x42, 0x8e, + 0xcc, 0x3b, 0xba, 0xf8, 0x78, 0xff, 0x86, 0xd4, 0xe4, 0x31, 0xa9, 0x9c, + 0xaf, 0x7e, 0x75, 0x3d, 0x55, 0xd3, 0xfb, 0x5e, 0xf4, 0xd1, 0x21, 0xb2, + 0xf0, 0xd7, 0x40, 0x01, 0x49, 0x3c, 0x61, 0xb3, 0x76, 0x66, 0xc8, 0x12, + 0x12, 0x8f, 0x66, 0x94, 0xf2, 0x26, 0x54, 0x4c, 0x98, 0xe0, 0x85, 0x74, + 0x2b, 0xb9, 0x8c, 0x40, 0xff, 0xdc, 0x12, 0xf8, 0xd5, 0x71, 0x76, 0x5c, + 0x51, 0xa9, 0x6e, 0x77, 0x33, 0xbb, 0xc2, 0x93, 0x53, 0x41, 0xab, 0x61, + 0xeb, 0x5e, 0x1a, 0xa6, 0xc4, 0x42, 0xfb, 0x62, 0x7b, 0xbb, 0x5c, 0x08, + 0x30, 0xa3, 0x8e, 0xa1, 0xb5, 0x5b, 0x65, 0x27, 0x6b, 0x20, 0x9e, 0x76, + 0x3d, 0x90, 0xe5, 0x35, 0xd9, 0xf8, 0x21, 0xec, 0xcd, 0x26, 0xc2, 0x8c, + 0x23, 0x37, 0x26, 0x04, 0x38, 0x95, 0xea, 0x95, 0x75, 0xc1, 0x40, 0x45, + 0x10, 0x93, 0xed, 0xff, 0x81, 0x96, 0xa1, 0x2b, 0x65, 0xee, 0x58, 0x8a, + 0x16, 0xb4, 0xb2, 0x17, 0xfc, 0x7c, 0x45, 0xc7, 0x32, 0x04, 0xdc, 0x06, + 0xce, 0x82, 0xca, 0x43, 0x66, 0x0a, 0x18, 0x7a, 0x83, 0x4c, 0x46, 0x2a, + 0x21, 0x82, 0xf2, 0xb8, 0xe9, 0x5e, 0x91, 0x86, 0x8b, 0x5e, 0x99, 0xc5, + 0xc7, 0xc8, 0xdb, 0x27, 0x45, 0xfb, 0x1a, 0x61, 0x99, 0x60, 0x2a, 0x0c, + 0xd8, 0x4f, 0x47, 0x75, 0xb2, 0xd3, 0xeb, 0x41, 0xb2, 0xe8, 0xff, 0x7c, + 0xed, 0xb5, 0x7f, 0xbc, 0x8c, 0xcd, 0x9b, 0x7c, 0x73, 0xc1, 0xa8, 0x76, + 0xe2, 0x2c, 0x00, 0x60, 0x9e, 0x4e, 0xd2, 0x0f, 0x4d, 0x0f, 0xea, 0x46, + 0x25, 0xf8, 0x3a, 0x91, 0x95, 0x8a, 0x11, 0x65, 0x43, 0xdd, 0xd6, 0x36, + 0x99, 0xa4, 0x17, 0x1d, 0xdf, 0x64, 0x5f, 0xad, 0x65, 0x57, 0xc7, 0x33, + 0x04, 0xbc, 0xf6, 0x29, 0xe8, 0x13, 0xf2, 0x79, 0x33, 0x3f, 0x45, 0x5e, + 0x02, 0x84, 0x2c, 0xf3, 0xbf, 0x21, 0x6f, 0x57, 0x49, 0x48, 0xb7, 0x3a, + 0xb7, 0xca, 0x2e, 0x4c, 0x94, 0x5f, 0x5d, 0xba, 0xa1, 0xc2, 0xe5, 0x76, + 0x38, 0x46, 0xf3, 0x2c, 0xd1, 0x8f, 0xcb, 0xb3, 0xa6, 0xb1, 0x6f, 0x9e, + 0x3f, 0x78, 0x5d, 0x1b, 0xa8, 0xfb, 0x18, 0xad, 0x67, 0xb0, 0xe9, 0x06, + 0x9a, 0xd7, 0x6a, 0xa3, 0x1e, 0x2e, 0xb4, 0xd1, 0xe0, 0xb5, 0x77, 0xbf, + 0xaa, 0x4f, 0xcc, 0x6b, 0xe6, 0xde, 0xf8, 0xd4, 0x18, 0x8e, 0x7a, 0xc4, + 0xff, 0xaf, 0xc2, 0xbc, 0xbe, 0x30, 0x3d, 0x62, 0xb4, 0xe6, 0xe4, 0x9d, + 0x70, 0x69, 0xd6, 0x2f, 0x50, 0xf2, 0x28, 0x1b, 0x6a, 0x3a, 0x06, 0x22, + 0xe3, 0xba, 0xe9, 0x4b, 0xb3, 0x47, 0x59, 0x83, 0x83, 0x83, 0xff, 0xb7, + 0x55, 0xbb, 0xcc, 0xcb, 0x17, 0x17, 0x08, 0x0f, 0x14, 0xd8, 0x82, 0xe2, + 0xe0, 0xb5, 0x0b, 0x53, 0xad, 0xdd, 0x79, 0x11, 0x19, 0x84, 0xa1, 0xe0, + 0xb5, 0xb7, 0xa9, 0xa2, 0x98, 0x84, 0xcc, 0x24, 0xe1, 0xe1, 0x24, 0xf3, + 0xfd, 0x24, 0x91, 0x31, 0xa8, 0xf5, 0x69, 0x64, 0x87, 0x39, 0x1b, 0x6c, + 0x1e, 0x2f, 0xf4, 0x14, 0x67, 0x10, 0x06, 0x03, 0x23, 0xde, 0xf0, 0xd3, + 0x25, 0x7f, 0x7f, 0x76, 0x86, 0x86, 0x56, 0x67, 0x1a, 0xff, 0x7f, 0xeb, + 0x43, 0xca, 0x11, 0x37, 0xd0, 0x6b, 0x8a, 0x9c, 0x4b, 0x49, 0xbd, 0x26, + 0x5d, 0xc7, 0x39, 0xb6, 0x8b, 0xef, 0x76, 0xd9, 0x53, 0x0f, 0xef, 0xb2, + 0x3d, 0xd2, 0x6a, 0xb9, 0xb7, 0xb9, 0xee, 0x3b, 0x04, 0x90, 0xff, 0xb9, + 0x2f, 0x75, 0xb8, 0xe0, 0x0c, 0xef, 0xe5, 0x36, 0x5b, 0xdf, 0xf1, 0xba, + 0x0a, 0x25, 0xaa, 0xa7, 0x21, 0x06, 0x98, 0x17, 0x63, 0xc4, 0xa4, 0x31, + 0xbc, 0x98, 0xba, 0xc1, 0x03, 0x16, 0x89, 0xeb, 0xf6, 0x6e, 0xe4, 0x15, + 0xb0, 0x44, 0x83, 0xb0, 0x9c, 0x13, 0xf9, 0x3e, 0xbe, 0x84, 0xd9, 0x20, + 0x85, 0x02, 0xa7, 0x43, 0x04, 0xd8, 0x0c, 0xaa, 0x55, 0xe4, 0x49, 0x05, + 0xa5, 0x22, 0x0f, 0x8f, 0x1e, 0xb2, 0xc4, 0xed, 0xc5, 0x86, 0xca, 0xb1, + 0xf3, 0xe3, 0x36, 0xae, 0x15, 0xd9, 0x2f, 0x64, 0x74, 0x15, 0x58, 0x86, + 0x01, 0x2e, 0xe1, 0x5a, 0x61, 0xf5, 0xe9, 0x0d, 0xa8, 0xe6, 0x4e, 0x35, + 0x66, 0x3a, 0xd6, 0x35, 0x01, 0x0b, 0x7b, 0x12, 0x11, 0x1b, 0x6b, 0xca, + 0x1a, 0x59, 0x98, 0x9e, 0x91, 0xeb, 0x74, 0xbf, 0xce, 0x41, 0xa0, 0x98, + 0x40, 0x07, 0x21, 0x96, 0xdb, 0x35, 0x78, 0x5b, 0x09, 0x93, 0x15, 0xe1, + 0xdb, 0xbb, 0xbf, 0x79, 0xac, 0x9a, 0x8c, 0x9d, 0x40, 0x93, 0x8b, 0xd0, + 0xb0, 0xcc, 0x9e, 0x28, 0xfd, 0x0d, 0x2f, 0xbb, 0x05, 0x62, 0xf5, 0x3d, + 0x8f, 0x0c, 0x68, 0x56, 0x50, 0x5e, 0xe5, 0x65, 0x6c, 0x50, 0x8a, 0xb2, + 0xb9, 0x75, 0x18, 0x6a, 0x9a, 0xeb, 0x01, 0x51, 0x20, 0x02, 0x00, 0x6b, + 0xd9, 0x95, 0xd2, 0x69, 0xc5, 0x7c, 0xc6, 0xdf, 0x28, 0xc7, 0xde, 0xcd, + 0xbe, 0xf1, 0x67, 0x9e, 0x32, 0xc6, 0x42, 0xdd, 0xfb, 0xcf, 0xe5, 0x72, + 0xd7, 0x36, 0x63, 0x33, 0x8a, 0xcf, 0xab, 0x56, 0x8d, 0x9b, 0x37, 0xed, + 0x17, 0x2c, 0xab, 0xbc, 0xc4, 0xc8, 0xe4, 0xc2, 0xb0, 0x45, 0x84, 0xde, + 0x5a, 0x70, 0xba, 0xb5, 0xa8, 0x67, 0x5f, 0xb1, 0xa8, 0x6e, 0x2b, 0x08, + 0xa9, 0x5a, 0xd5, 0x0f, 0x59, 0x90, 0xfc, 0x60, 0x48, 0x07, 0x2f, 0xbb, + 0xed, 0x84, 0xfb, 0x4d, 0xd9, 0x8c, 0x0c, 0xbb, 0xb9, 0x1f, 0x28, 0x02, + 0x51, 0x71, 0xa0, 0x9a, 0xc8, 0xf0, 0x10, 0x9c, 0xf0, 0xdb, 0xca, 0x64, + 0x37, 0x77, 0xb1, 0x5d, 0x92, 0xc1, 0x39, 0x96, 0x44, 0x26, 0xd7, 0x26, + 0x03, 0x52, 0x04, 0x48, 0x64, 0x3f, 0x1b, 0x53, 0xd6, 0x38, 0xab, 0x2c, + 0x8e, 0x6b, 0xe3, 0x7e, 0x46, 0xfa, 0x9b, 0xb0, 0x89, 0xad, 0x5f, 0x96, + 0x61, 0x61, 0x60, 0x2d, 0x33, 0x05, 0x95, 0xa0, 0x29, 0xfb, 0x65, 0x28, + 0x14, 0x1c, 0x94, 0x4e, 0x23, 0x18, 0x37, 0x87, 0x5a, 0x46, 0xee, 0xc4, + 0x7e, 0x1c, 0x8b, 0x8a, 0xf3, 0xac, 0x46, 0xcd, 0x8f, 0x9f, 0x2b, 0x3b, + 0xce, 0x38, 0x90, 0xf3, 0xef, 0x15, 0xfa, 0xd8, 0xe9, 0x4b, 0xfe, 0xf9, + 0x45, 0x2c, 0xb8, 0xf3, 0x00, 0xde, 0xd9, 0x81, 0xb0, 0x55, 0x59, 0x44, + 0x92, 0x37, 0xd1, 0x38, 0x91, 0x90, 0xee, 0xec, 0x68, 0x02, 0x23, 0xfa, + 0x6d, 0x05, 0xc4, 0x7f, 0xbc, 0xc2, 0x7c, 0x24, 0x5b, 0x9a, 0xc4, 0x4e, + 0xb3, 0xac, 0x00, 0xcc, 0xa7, 0xde, 0x32, 0x35, 0xf5, 0x5d, 0x4e, 0x45, + 0x4d, 0x1b, 0xf7, 0x98, 0xf5, 0x59, 0x3e, 0xc9, 0x4f, 0xbb, 0xc1, 0x48, + 0x41, 0x85, 0x68, 0x7d, 0x5f, 0x72, 0x20, 0xa4, 0xcf, 0x47, 0xa6, 0xa8, + 0xcb, 0x7a, 0xab, 0xe1, 0xf8, 0xa8, 0x8a, 0xa5, 0xf9, 0xfe, 0x89, 0x3d, + 0x9e, 0xbe, 0x6c, 0x4c, 0x70, 0xb3, 0xbf, 0xdf, 0xf4, 0xe6, 0x4f, 0x78, + 0x1f, 0x25, 0xca, 0x3c, 0x1e, 0xd1, 0x61, 0x3a, 0xda, 0xf7, 0xfa, 0xf5, + 0x7a, 0xc3, 0x7c, 0x14, 0x23, 0x28, 0x4b, 0x36, 0x78, 0xcd, 0xba, 0xdc, + 0x7f, 0xf5, 0x82, 0xf0, 0x1c, 0x5e, 0xd2, 0x19, 0x04, 0x1d, 0x43, 0x81, + 0x05, 0x97, 0x84, 0x87, 0xff, 0x4e, 0x04, 0xed, 0x45, 0xae, 0x7b, 0xa9, + 0x5b, 0xa6, 0xd0, 0x01, 0xdc, 0xbe, 0x3b, 0xd0, 0x9a, 0x1b, 0xfd, 0xf0, + 0x33, 0x58, 0xcb, 0x00, 0xfd, 0xf8, 0x2d, 0x30, 0x80, 0x12, 0x8c, 0x4c, + 0xfb, 0xf1, 0xe7, 0x0f, 0xe5, 0x00, 0x31, 0x0e, 0x24, 0x8f, 0xc1, 0x79, + 0x24, 0x2e, 0x35, 0xe1, 0x90, 0x77, 0x10, 0x79, 0xbf, 0x98, 0xd0, 0x08, + 0xa0, 0xb1, 0x39, 0x50, 0x70, 0xc9, 0x05, 0x91, 0x54, 0x4a, 0xbc, 0x26, + 0x5e, 0xa2, 0x47, 0x1c, 0xcf, 0x22, 0x1a, 0xa9, 0xda, 0x22, 0x98, 0x76, + 0x20, 0x30, 0xb4, 0x18, 0x05, 0x40, 0x67, 0x96, 0xef, 0x9b, 0x6b, 0x1a, + 0x9a, 0xe7, 0x3d, 0x49, 0x62, 0x00, 0x6b, 0xf7, 0x1b, 0xe3, 0x81, 0xfe, + 0x8f, 0x1d, 0xdb, 0x33, 0xf8, 0x8b, 0x24, 0x39, 0xe3, 0xdd, 0x2c, 0xfd, + 0x24, 0xb1, 0x31, 0xa8, 0x44, 0xf6, 0x89, 0x7a, 0x88, 0x45, 0x53, 0xab, + 0x47, 0x3f, 0x5c, 0xe1, 0x42, 0x1e, 0x27, 0xc2, 0xb4, 0x29, 0x40, 0xe6, + 0x9c, 0x2b, 0xae, 0x7f, 0x7f, 0xc3, 0x4c, 0x2e, 0xe0, 0x4c, 0x35, 0x28, + 0x34, 0xa3, 0x1d, 0xb8, 0x05, 0x33, 0xd0, 0x51, 0x31, 0x29, 0x31, 0x21, + 0x62, 0x7d, 0x2a, 0x2e, 0xfb, 0xed, 0x0a, 0xf8, 0x7a, 0x83, 0xfc, 0xd5, + 0xd4, 0x7d, 0x33, 0x0c, 0x9f, 0x37, 0x02, 0xd4, 0xf7, 0x44, 0xbc, 0x57, + 0x80, 0x35, 0x1a, 0x36, 0x67, 0xae, 0xba, 0x8d, 0xb8, 0x42, 0xff, 0x0c, + 0xdf, 0x13, 0xfd, 0x83, 0x1c, 0x63, 0x1d, 0xf0, 0x51, 0x0e, 0x71, 0xf6, + 0xa5, 0x41, 0x7d, 0x1c, 0xfc, 0xe4, 0xb6, 0x62, 0x7d, 0xa6, 0x63, 0x7d, + 0xeb, 0x0f, 0x0e, 0x80, 0x4e, 0xeb, 0xa7, 0x76, 0xd3, 0xb1, 0x66, 0x7f, + 0xce, 0xd2, 0xe9, 0x41, 0x9e, 0x06, 0x17, 0xa9, 0x93, 0x0c, 0xa8, 0x21, + 0xc5, 0xe4, 0x76, 0xd1, 0x30, 0xb6, 0x17, 0x92, 0xf2, 0xec, 0xdd, 0x94, + 0xc6, 0xad, 0x9b, 0x45, 0x1e, 0x91, 0xbf, 0x72, 0xc6, 0x7f, 0xa8, 0x9e, + 0x78, 0xf1, 0x4a, 0x45, 0x93, 0x88, 0xc5, 0x99, 0x68, 0x6a, 0xc2, 0xe9, + 0x99, 0x66, 0x74, 0x23, 0x26, 0xb0, 0x30, 0x07, 0xc9, 0x09, 0x21, 0xdd, + 0x51, 0x91, 0x8a, 0x09, 0x11, 0x50, 0x8f, 0x4e, 0x4b, 0x31, 0x97, 0xa5, + 0xf5, 0x8e, 0x2b, 0x11, 0x00, 0x55, 0x1e, 0x56, 0x56, 0x1f, 0xf0, 0xd0, + 0x3a, 0x1c, 0xe3, 0xec, 0xc3, 0x84, 0x94, 0xcb, 0x80, 0x94, 0x3b, 0xe6, + 0x4d, 0x88, 0x4f, 0x7f, 0x31, 0x57, 0x5f, 0xd7, 0xb7, 0x0a, 0x41, 0xb1, + 0xdf, 0x93, 0xa6, 0xf6, 0x76, 0xb4, 0xb8, 0x40, 0xcb, 0xcb, 0xea, 0x99, + 0x7f, 0x49, 0x14, 0xae, 0xc1, 0xf2, 0x38, 0x2e, 0xb9, 0x70, 0x6e, 0x7b, + 0x55, 0x5e, 0x8a, 0x2a, 0xf5, 0x10, 0x4d, 0xdf, 0xff, 0xfc, 0xf8, 0x04, + 0x91, 0xc7, 0x57, 0xf6, 0x88, 0x22, 0x17, 0xff, 0xe1, 0xc8, 0xfd, 0x06, + 0x20, 0x1d, 0xe1, 0x67, 0x2f, 0xa8, 0xe8, 0x15, 0xc9, 0x14, 0x65, 0xc7, + 0x18, 0x92, 0x81, 0xe2, 0x56, 0x02, 0x40, 0x11, 0xcd, 0x17, 0xdc, 0x25, + 0x24, 0x9f, 0x30, 0xc3, 0x91, 0x9a, 0x03, 0x41, 0xd4, 0x47, 0x8c, 0x5b, + 0xf6, 0x76, 0x90, 0x0e, 0x78, 0xc0, 0x82, 0xc0, 0xf7, 0xb5, 0x53, 0x3e, + 0x1d, 0x85, 0x10, 0xd2, 0x42, 0x71, 0x94, 0x37, 0x26, 0x8d, 0x3f, 0x5f, + 0x61, 0xeb, 0xd4, 0xb2, 0x72, 0x46, 0xf2, 0x3d, 0xc2, 0xd2, 0xfc, 0x6c, + 0x23, 0x47, 0xd3, 0x98, 0x87, 0x9f, 0x0c, 0xcd, 0xa9, 0x3e, 0xec, 0xe8, + 0x6c, 0x48, 0x75, 0x6c, 0x9b, 0x22, 0x45, 0x8d, 0x62, 0x7f, 0x3d, 0x12, + 0x4b, 0xa5, 0x3d, 0x3f, 0xd8, 0xe6, 0x3a, 0x02, 0x2d, 0xc9, 0x55, 0x54, + 0x47, 0x08, 0xb8, 0x51, 0xcf, 0x96, 0x6d, 0xb6, 0x16, 0xbe, 0xf6, 0x96, + 0x00, 0x4b, 0xcb, 0x02, 0xd1, 0xc7, 0x1c, 0xe1, 0xaa, 0xed, 0x29, 0x8a, + 0xe4, 0x43, 0x04, 0x8f, 0x71, 0x7a, 0x02, 0x46, 0xde, 0xdf, 0x90, 0xa4, + 0xf7, 0x52, 0x69, 0xe7, 0x79, 0x4b, 0x91, 0x3c, 0xc8, 0xa0, 0x3e, 0xef, + 0x25, 0xab, 0xb5, 0xdb, 0xff, 0x48, 0x23, 0xf8, 0xa8, 0x17, 0xa5, 0x69, + 0xf2, 0xd0, 0xea, 0xdd, 0x58, 0x27, 0xec, 0xd4, 0xe3, 0x39, 0x75, 0x20, + 0x65, 0x19, 0x40, 0x25, 0x9a, 0xca, 0xbd, 0x6d, 0x92, 0x73, 0x9a, 0xe0, + 0x27, 0xc4, 0x0b, 0x5e, 0x53, 0xc4, 0x26, 0x95, 0x6b, 0x36, 0x4e, 0x1d, + 0x47, 0x00, 0xec, 0x5d, 0xe0, 0x92, 0xf8, 0x6c, 0x49, 0x74, 0x88, 0xb4, + 0x0e, 0x10, 0x71, 0xcd, 0xe8, 0x5b, 0x7a, 0x46, 0xd4, 0xca, 0xd5, 0x3d, + 0xcf, 0x50, 0x0f, 0x31, 0x85, 0x45, 0x12, 0x91, 0x78, 0xb9, 0xda, 0xb4, + 0x96, 0xc1, 0x82, 0xbc, 0x15, 0x4f, 0x59, 0xcf, 0x7c, 0xe4, 0xfe, 0x9b, + 0xe6, 0x4b, 0xad, 0xbb, 0xbd, 0x5e, 0x31, 0xc7, 0x7f, 0x23, 0x9c, 0x4d, + 0x03, 0x08, 0x41, 0x83, 0xbf, 0xe2, 0xe3, 0x97, 0xcf, 0x19, 0x88, 0x7a, + 0x5f, 0xa3, 0xa6, 0x09, 0x9a, 0xc5, 0x93, 0xaa, 0x7b, 0x15, 0x96, 0xfc, + 0x02, 0x0c, 0x00, 0x1d, 0xca, 0x21, 0x10, 0x30, 0x48, 0xff, 0x89, 0x07, + 0x28, 0xc5, 0x66, 0x44, 0xa7, 0x1e, 0xe3, 0x89, 0xd7, 0xaf, 0x97, 0xca, + 0x24, 0x6d, 0xe3, 0x1d, 0x80, 0x9a, 0x0f, 0x83, 0xef, 0xdb, 0x37, 0xc0, + 0x8e, 0xac, 0x00, 0x6c, 0xbf, 0x01, 0x3f, 0xda, 0xdf, 0x09, 0x9f, 0x36, + 0x68, 0x08, 0x06, 0xb3, 0x36, 0xee, 0x6b, 0x28, 0xcb, 0x27, 0xa5, 0x6f, + 0x49, 0x40, 0x34, 0xc0, 0x64, 0x65, 0x07, 0x5d, 0xa4, 0x28, 0xe9, 0xd9, + 0x1c, 0xc4, 0x42, 0x2d, 0xf7, 0xcc, 0x14, 0x3e, 0x02, 0x35, 0x54, 0x7c, + 0x38, 0xc0, 0xb5, 0xfb, 0x2e, 0x82, 0xed, 0xbf, 0xec, 0x37, 0xd3, 0x93, + 0x91, 0x95, 0x00, 0xcc, 0x1b, 0x83, 0x9a, 0x57, 0x16, 0x8c, 0xf8, 0x4d, + 0x5e, 0x4e, 0x0d, 0x1b, 0xc3, 0xc2, 0xec, 0xa7, 0x26, 0x84, 0xe4, 0x11, + 0x72, 0x9b, 0x0d, 0xf5, 0x7e, 0xae, 0xa6, 0xa4, 0x57, 0x14, 0x4c, 0x86, + 0x59, 0x30, 0xa8, 0xbb, 0xfe, 0xc3, 0x5a, 0xa3, 0x40, 0xcd, 0x65, 0xce, + 0x69, 0xff, 0xa6, 0xe7, 0xdd, 0x88, 0xa8, 0xaa, 0xc9, 0x99, 0x26, 0x1b, + 0x42, 0x80, 0xe0, 0x26, 0x26, 0x03, 0xcd, 0x33, 0x05, 0xab, 0x2b, 0xe5, + 0x44, 0xc6, 0x7a, 0xf3, 0xdd, 0x0f, 0xb6, 0x1a, 0x06, 0x28, 0xca, 0x1c, + 0xd9, 0x50, 0xa4, 0x8c, 0xb7, 0xbb, 0xc8, 0x88, 0x28, 0xd0, 0x00, 0xe0, + 0xda, 0xc5, 0x8a, 0x6c, 0xcd, 0xf8, 0x8d, 0xed, 0x8c, 0x88, 0x11, 0x11, + 0xa8, 0xeb, 0x43, 0x94, 0x24, 0xee, 0x01, 0xd1, 0x7c, 0x8c, 0x17, 0x99, + 0xe8, 0x8e, 0x5d, 0x16, 0x90, 0x6f, 0x93, 0xf5, 0xab, 0x1c, 0x21, 0xa0, + 0xf0, 0x92, 0xd5, 0x87, 0x4e, 0xd4, 0x7b, 0xc9, 0x31, 0xb2, 0x32, 0x6b, + 0x6f, 0x6c, 0x8c, 0xfd, 0xf7, 0x00, 0x59, 0xfc, 0x72, 0xd6, 0xff, 0x7c, + 0x2f, 0xfc, 0xfd, 0x1c, 0x22, 0xb5, 0xb2, 0xd7, 0xf3, 0x1c, 0xcc, 0x3a, + 0xe0, 0x72, 0xa5, 0xaf, 0xf7, 0xdb, 0xa1, 0x40, 0x76, 0xcd, 0x14, 0x30, + 0x0c, 0x20, 0xe7, 0xd5, 0xdc, 0x14, 0x67, 0x01, 0xdf, 0x48, 0xf0, 0x22, + 0x3f, 0x62, 0xcd, 0x13, 0x28, 0xd6, 0xf2, 0xf6, 0x14, 0xfe, 0xaa, 0x93, + 0x5a, 0xc3, 0xd2, 0x2f, 0xcf, 0xc9, 0xe4, 0x94, 0xb9, 0x5c, 0x46, 0x2a, + 0xdf, 0xf6, 0xc9, 0x16, 0xb8, 0xf4, 0x7e, 0x61, 0xe5, 0x47, 0xac, 0xff, + 0x37, 0x80, 0x09, 0x87, 0xe6, 0xf4, 0x7c, 0x1a, 0xfd, 0x49, 0x97, 0xfc, + 0x7f, 0xea, 0x15, 0x3f, 0xf5, 0x27, 0x05, 0xb2, 0xc9, 0x6d, 0xaa, 0x87, + 0xe1, 0xe9, 0x4f, 0xa0, 0x06, 0x20, 0x80, 0x08, 0x78, 0xee, 0x5c, 0xb6, + 0x64, 0x74, 0x6c, 0x18, 0xcf, 0x82, 0x54, 0xd5, 0x48, 0x7c, 0x01, 0x50, + 0x0e, 0x97, 0x33, 0xe1, 0xd1, 0x83, 0xd3, 0xe1, 0x48, 0x6e, 0xee, 0xf7, + 0x5f, 0x6d, 0x1f, 0x03, 0x9c, 0x74, 0xcf, 0x97, 0x66, 0x95, 0x95, 0x71, + 0x3e, 0x82, 0x0d, 0xc8, 0xa8, 0x92, 0x64, 0xc1, 0x9a, 0xd8, 0xc6, 0x20, + 0x4c, 0x32, 0x6c, 0x1b, 0xf0, 0xa5, 0xcb, 0xa4, 0x0b, 0xdd, 0x42, 0x08, + 0x54, 0x13, 0xec, 0xe6, 0x6b, 0xa2, 0x49, 0x96, 0x9c, 0xd9, 0x25, 0x12, + 0x48, 0x10, 0xc4, 0xc1, 0xd1, 0x99, 0xf5, 0xc4, 0x36, 0x56, 0x12, 0xed, + 0x23, 0x02, 0x21, 0x43, 0xa2, 0x8c, 0x3e, 0xdb, 0xdf, 0x7a, 0xd8, 0x32, + 0xed, 0xf7, 0xc0, 0xf4, 0x79, 0x51, 0x85, 0x94, 0x29, 0x4f, 0x3b, 0x7d, + 0xe4, 0x54, 0x94, 0x7d, 0x2b, 0xef, 0xa0, 0x74, 0x63, 0x47, 0x2c, 0x9b, + 0xd1, 0x71, 0xca, 0x64, 0x41, 0x7d, 0xbe, 0x44, 0xeb, 0x25, 0xcb, 0x53, + 0xb0, 0x46, 0x1d, 0x8a, 0x39, 0x30, 0x55, 0xf0, 0x7e, 0xb4, 0x17, 0xda, + 0x34, 0x35, 0xb9, 0x7f, 0xc1, 0x85, 0x2c, 0x95, 0x66, 0xe5, 0xd1, 0xb9, + 0x46, 0xa0, 0x6d, 0x47, 0xee, 0xc4, 0x3f, 0x0e, 0x91, 0x1a, 0xc7, 0x0b, + 0x9e, 0x2c, 0x45, 0x25, 0xf0, 0x63, 0xdd, 0x15, 0x09, 0x2f, 0x8d, 0x1b, + 0xde, 0x4b, 0x39, 0x1c, 0xbb, 0xf2, 0xc8, 0x12, 0x09, 0xe1, 0xfc, 0x90, + 0xc4, 0xc4, 0x44, 0xe9, 0x09, 0x7b, 0xb5, 0xf4, 0x40, 0x54, 0xb0, 0x85, + 0x8c, 0xd2, 0x87, 0x68, 0x06, 0x04, 0x08, 0xd3, 0x63, 0xcb, 0xd8, 0x8b, + 0x75, 0x89, 0x3c, 0xb1, 0x3e, 0xad, 0x16, 0xc1, 0xc2, 0x1f, 0x4d, 0x3c, + 0xfe, 0x2f, 0x5d, 0x60, 0x85, 0xa8, 0xd3, 0xda, 0x45, 0xd9, 0xe2, 0x52, + 0xe2, 0x5f, 0x89, 0xce, 0x23, 0xc4, 0xb4, 0x99, 0x6b, 0x5a, 0x6c, 0xe1, + 0x1d, 0xcb, 0x67, 0x87, 0x0f, 0x9c, 0xa5, 0x1f, 0x97, 0x54, 0x80, 0xb0, + 0xf1, 0x40, 0xc5, 0x07, 0xbd, 0xbf, 0xd5, 0x57, 0x85, 0xdb, 0x63, 0xc2, + 0x20, 0x08, 0xe3, 0xb2, 0xb3, 0x12, 0xdf, 0x3c, 0x6b, 0x4b, 0xf1, 0x44, + 0xde, 0x32, 0xbd, 0xcb, 0x80, 0xbf, 0xdd, 0x9f, 0xa5, 0x9f, 0x92, 0x6b, + 0xfd, 0xcf, 0x5b, 0x03, 0xc7, 0xb1, 0xe7, 0xf4, 0x18, 0x90, 0xbc, 0x3b, + 0xc2, 0x5e, 0xf6, 0x26, 0xce, 0xfe, 0xce, 0x14, 0xbe, 0x1e, 0x4b, 0x31, + 0xd5, 0x96, 0x79, 0x71, 0x94, 0xbe, 0x23, 0x7f, 0x24, 0x2b, 0xb9, 0xe0, + 0x2d, 0xde, 0x56, 0x6f, 0x5c, 0x08, 0x6c, 0x16, 0xfb, 0xb1, 0x71, 0x26, + 0x63, 0x39, 0x88, 0xf1, 0x3d, 0xe7, 0xf4, 0x48, 0x94, 0x93, 0x55, 0xc6, + 0xd3, 0x13, 0xde, 0xe2, 0x63, 0xcb, 0xdf, 0x75, 0x38, 0x10, 0xb1, 0x43, + 0xdd, 0xa2, 0x4a, 0xae, 0x86, 0x7a, 0x11, 0xfc, 0x7b, 0x50, 0x0e, 0xa4, + 0x63, 0x04, 0xf0, 0x39, 0x49, 0x50, 0xdb, 0xa9, 0x9e, 0xfb, 0xfb, 0xbb, + 0x60, 0x0f, 0x16, 0x84, 0x17, 0xb5, 0xc1, 0x26, 0x07, 0x67, 0xa9, 0xf3, + 0x53, 0x98, 0x3a, 0xe5, 0x42, 0xf9, 0x32, 0x7a, 0xf0, 0x93, 0xdd, 0x0c, + 0xdb, 0x4e, 0x87, 0x35, 0x2e, 0x45, 0x51, 0xa7, 0x3f, 0xe4, 0x49, 0xcf, + 0xc8, 0xb1, 0x21, 0x7f, 0xf8, 0xd3, 0xc5, 0x12, 0xf0, 0x9b, 0x16, 0xdd, + 0x2d, 0xf1, 0xb6, 0x58, 0x8b, 0x5d, 0xe1, 0xd2, 0xfe, 0xa9, 0x7c, 0x5d, + 0x68, 0x32, 0xea, 0xd6, 0xea, 0x89, 0xa3, 0x29, 0x42, 0x31, 0x7c, 0x0f, + 0x2c, 0x4d, 0x77, 0x64, 0xe7, 0x3e, 0xe7, 0x20, 0x20, 0xe5, 0xf8, 0x0a, + 0x68, 0x1c, 0x91, 0x9a, 0x62, 0x78, 0x72, 0xca, 0x37, 0x7b, 0x91, 0x2e, + 0xc2, 0x93, 0xc8, 0x4f, 0xa7, 0x21, 0x1c, 0xc8, 0x07, 0xec, 0x83, 0xc9, + 0xb7, 0x65, 0x63, 0x1d, 0x29, 0x07, 0x64, 0x4c, 0xf4, 0x5f, 0xf2, 0xda, + 0x4d, 0xb0, 0xba, 0x86, 0xe7, 0x8b, 0x8a, 0x7e, 0x1b, 0x89, 0xb1, 0x6b, + 0x2d, 0x2b, 0xe2, 0xa6, 0x73, 0x68, 0xe4, 0xe2, 0xee, 0x58, 0x55, 0xfe, + 0xa1, 0xfa, 0x12, 0xfd, 0x09, 0xec, 0xfa, 0xef, 0x59, 0xd1, 0xbb, 0xca, + 0x8d, 0x82, 0x94, 0xcd, 0xfd, 0x8f, 0x18, 0xd8, 0x16, 0xd7, 0x67, 0x3b, + 0x38, 0x44, 0x44, 0xa1, 0x7a, 0xc5, 0x2f, 0x4d, 0x4d, 0x19, 0xf8, 0xf9, + 0xf9, 0x9d, 0x0f, 0x16, 0x44, 0x59, 0xd8, 0xd8, 0xd0, 0x63, 0x5f, 0x8e, + 0xbc, 0xea, 0x02, 0x11, 0x54, 0xcf, 0xda, 0x67, 0x96, 0x14, 0x5d, 0x37, + 0x12, 0x8c, 0xd1, 0xc5, 0xe7, 0x05, 0xc2, 0x90, 0x37, 0xa5, 0xae, 0x22, + 0x23, 0xb5, 0xa6, 0x01, 0x89, 0xc6, 0x24, 0x00, 0xa3, 0xb9, 0xe8, 0xbd, + 0x7b, 0x4b, 0xd5, 0x6e, 0xf2, 0x2d, 0xa4, 0x7a, 0xd6, 0xce, 0x82, 0x5a, + 0xae, 0x31, 0x48, 0xf0, 0x6b, 0x0e, 0x74, 0xd9, 0xdc, 0x71, 0xc9, 0xb4, + 0xca, 0x12, 0xf7, 0xa0, 0x61, 0x8b, 0xa1, 0xee, 0xe6, 0xdb, 0xb7, 0x6f, + 0x16, 0x5b, 0x23, 0xe9, 0xca, 0xca, 0xca, 0xed, 0xc7, 0xeb, 0x7d, 0x2e, + 0x17, 0x7b, 0x06, 0x02, 0x02, 0x02, 0x08, 0x50, 0xfd, 0x90, 0x23, 0x4f, + 0x03, 0x3e, 0x87, 0x59, 0x9e, 0xd6, 0x4b, 0x07, 0x0f, 0x11, 0xb9, 0x8c, + 0xc4, 0x8d, 0x3c, 0xbc, 0x3a, 0x76, 0x08, 0x25, 0xb0, 0x11, 0x7b, 0x7d, + 0x0c, 0x81, 0x72, 0xa9, 0x85, 0xab, 0xee, 0x2c, 0xf3, 0x43, 0x96, 0x0e, + 0x1c, 0x34, 0xd0, 0x84, 0xfc, 0x0f, 0xe7, 0x52, 0xfd, 0x6e, 0xaf, 0x8e, + 0x29, 0x17, 0x02, 0xb6, 0xc7, 0xb2, 0x51, 0xef, 0xed, 0x3d, 0x05, 0xf8, + 0x9f, 0x75, 0x73, 0x24, 0x3d, 0x62, 0x54, 0xfa, 0xa1, 0xb9, 0xb2, 0x3b, + 0xbb, 0x76, 0xf6, 0x84, 0x11, 0x34, 0xe8, 0x5f, 0x30, 0x1e, 0x99, 0xf6, + 0xbe, 0x92, 0xa5, 0xd6, 0xd4, 0x38, 0xdd, 0x18, 0x7c, 0xee, 0xca, 0x6e, + 0x1a, 0x58, 0x97, 0xa6, 0xf3, 0xed, 0x3b, 0x50, 0xc6, 0x80, 0xa5, 0xa1, + 0xc3, 0x8b, 0xf6, 0xd5, 0xd8, 0xaf, 0x75, 0xcc, 0x4f, 0x9e, 0x8c, 0x35, + 0x79, 0x1e, 0xaa, 0x49, 0x49, 0x71, 0x70, 0xe0, 0xbc, 0x9b, 0x2e, 0xeb, + 0x59, 0xed, 0x0a, 0x75, 0xf9, 0x5b, 0x5a, 0x27, 0x36, 0xa5, 0xff, 0x84, + 0x2b, 0x89, 0xf4, 0x46, 0xb7, 0xa8, 0x3f, 0x5f, 0x3e, 0xd4, 0x1f, 0xe2, + 0x61, 0xde, 0x2f, 0x15, 0x45, 0x22, 0x06, 0xa5, 0xdb, 0xda, 0xac, 0xd0, + 0xb3, 0x5a, 0x29, 0xd5, 0x33, 0x67, 0x46, 0x78, 0xc5, 0x84, 0xef, 0x1a, + 0x3a, 0x2c, 0xaf, 0xcf, 0x05, 0x66, 0x48, 0x07, 0x48, 0x29, 0x1c, 0x9f, + 0x9c, 0xf0, 0xc0, 0x08, 0xd6, 0x7b, 0xa3, 0xba, 0xca, 0x4c, 0x9a, 0x9c, + 0x57, 0xda, 0xd1, 0xce, 0x76, 0x26, 0x0a, 0x2a, 0x7b, 0xb3, 0x2b, 0x67, + 0x5d, 0xcd, 0xd4, 0x5f, 0x07, 0xd8, 0xf9, 0x63, 0x07, 0xef, 0x9d, 0xa2, + 0x8a, 0x59, 0xc7, 0x64, 0x1e, 0x94, 0x30, 0x5b, 0xe4, 0x46, 0x85, 0x88, + 0xc5, 0x9f, 0xf1, 0xe3, 0x25, 0xa6, 0x28, 0x2e, 0xf5, 0x9e, 0x37, 0xe7, + 0x5d, 0x59, 0x0d, 0x65, 0x74, 0xbc, 0xfc, 0x47, 0x05, 0x4b, 0xe1, 0x7d, + 0x8b, 0x6e, 0x01, 0x83, 0xf1, 0x01, 0x36, 0x36, 0x5d, 0x9b, 0x5a, 0x6c, + 0xd1, 0xc0, 0xae, 0xfb, 0xe4, 0x98, 0xf3, 0xa8, 0x83, 0xa8, 0x70, 0x98, + 0xba, 0xd1, 0xef, 0xaa, 0x48, 0xb8, 0x7d, 0x36, 0xe9, 0x5a, 0x29, 0x40, + 0x50, 0xe4, 0x5f, 0x57, 0xb4, 0x84, 0xfc, 0x6f, 0xbd, 0xce, 0xb6, 0xc7, + 0xd7, 0xc3, 0x47, 0x17, 0xcb, 0xcd, 0xa4, 0xf7, 0x66, 0xab, 0xb1, 0xa1, + 0x50, 0x68, 0x14, 0x6b, 0x34, 0x28, 0xeb, 0x02, 0x3b, 0x6b, 0x34, 0x31, + 0x73, 0xa1, 0x0f, 0x28, 0x97, 0xf0, 0xf5, 0x05, 0xc3, 0xf9, 0x2a, 0x87, + 0xb5, 0x99, 0xd5, 0xb1, 0xbf, 0x02, 0x07, 0x1e, 0xec, 0x08, 0x8e, 0x3d, + 0x7d, 0x57, 0xac, 0x68, 0x3a, 0xe9, 0x7d, 0x2d, 0x21, 0xf8, 0xe6, 0x4f, + 0x42, 0xf1, 0x80, 0xe5, 0x56, 0x3f, 0xd4, 0x0d, 0xed, 0x0a, 0x8a, 0x8a, + 0x42, 0x49, 0xfa, 0x9d, 0x1f, 0xab, 0xd2, 0x65, 0xc8, 0xfc, 0x9e, 0xfe, + 0xf8, 0x08, 0x40, 0x58, 0x4c, 0x38, 0xf2, 0xfe, 0xb1, 0x94, 0xfe, 0xad, + 0x30, 0x6f, 0x2f, 0x77, 0xeb, 0x0b, 0x48, 0x9e, 0x36, 0x40, 0x50, 0x17, + 0x5f, 0xd3, 0xb9, 0xad, 0x14, 0x73, 0x89, 0x89, 0x24, 0x8e, 0x64, 0x42, + 0x4d, 0x6d, 0xfa, 0x63, 0x21, 0xca, 0x2a, 0x2a, 0x1d, 0xb9, 0x31, 0x52, + 0x73, 0xfa, 0x16, 0x0c, 0xc3, 0xfa, 0x3b, 0x8e, 0xa5, 0x1e, 0xb7, 0x59, + 0x84, 0x2d, 0xb1, 0x44, 0x28, 0x2a, 0xd7, 0x80, 0xda, 0x61, 0xa6, 0xc8, + 0x0c, 0x20, 0xc1, 0x4e, 0x64, 0x9e, 0x4f, 0xe8, 0x2b, 0x8f, 0x07, 0xb8, + 0xad, 0x5e, 0x4b, 0x9e, 0xeb, 0x84, 0x4a, 0x38, 0x3a, 0x0d, 0xd8, 0x0a, + 0x58, 0x9c, 0xef, 0x4e, 0xa5, 0x88, 0xb9, 0x3f, 0x03, 0x05, 0x9e, 0x5e, + 0xd3, 0x96, 0xfe, 0xfe, 0xc2, 0x2c, 0xb6, 0x78, 0xe5, 0x4f, 0xef, 0xcf, + 0xc7, 0x08, 0xec, 0x71, 0x1c, 0xd1, 0x7c, 0x85, 0x85, 0x46, 0xcf, 0x7f, + 0xd0, 0x08, 0x5a, 0x2f, 0x79, 0x30, 0x73, 0xa4, 0x93, 0xae, 0xa5, 0xb7, + 0xce, 0xd5, 0x4e, 0x5b, 0x19, 0xe5, 0x8e, 0x9b, 0x1f, 0x2c, 0x34, 0x30, + 0x34, 0x65, 0x30, 0xe1, 0xe8, 0x57, 0xac, 0x4c, 0xbf, 0x34, 0xb5, 0x6c, + 0x10, 0xea, 0xb7, 0x50, 0xb9, 0x69, 0xea, 0xe3, 0x9e, 0x09, 0x46, 0xd1, + 0x43, 0xa0, 0x70, 0x0c, 0x7c, 0x67, 0xaa, 0x1a, 0xfb, 0xfe, 0x2c, 0x74, + 0xe0, 0xac, 0x3e, 0x1d, 0xcc, 0xf3, 0xc5, 0x87, 0x8d, 0xf2, 0x86, 0x28, + 0xd3, 0xf9, 0xe9, 0x87, 0x95, 0x8f, 0xd8, 0x60, 0x06, 0x86, 0x83, 0xf1, + 0xbf, 0x1a, 0x48, 0x91, 0x71, 0x2b, 0xa4, 0xd8, 0xd6, 0xef, 0x26, 0x09, + 0x9f, 0x0e, 0xee, 0x70, 0x60, 0xa9, 0xe8, 0x69, 0xeb, 0xaa, 0x4a, 0x32, + 0x38, 0x76, 0xf3, 0xff, 0x3c, 0xb7, 0xc6, 0x9d, 0xfb, 0xdb, 0x34, 0x58, + 0x98, 0xc3, 0x9f, 0x6c, 0x0e, 0x7f, 0xdd, 0x3a, 0x7e, 0xf7, 0xa2, 0xb7, + 0xc2, 0x61, 0x96, 0x5f, 0x39, 0x7e, 0x92, 0x2a, 0xa2, 0xc1, 0x4c, 0xa6, + 0x9d, 0xfe, 0xc7, 0xbd, 0x3c, 0x3e, 0xb0, 0xb9, 0xac, 0x89, 0x08, 0xb3, + 0x3d, 0x43, 0x51, 0xc7, 0xfb, 0x59, 0xef, 0x9e, 0x99, 0x1b, 0xb5, 0x78, + 0xb5, 0xd9, 0xe5, 0x87, 0x7b, 0xcf, 0xe4, 0x42, 0x63, 0x71, 0x2d, 0x7f, + 0x7f, 0x29, 0xb6, 0xd7, 0x19, 0x91, 0x01, 0xb7, 0xeb, 0x8c, 0xb1, 0x56, + 0xd4, 0xb9, 0x8a, 0x51, 0x9d, 0xe9, 0x9e, 0x4b, 0xb3, 0xfa, 0x7f, 0x63, + 0xed, 0xed, 0xe3, 0xcb, 0x4e, 0xfa, 0x83, 0x9b, 0x78, 0x51, 0x65, 0x13, + 0x79, 0x27, 0xa6, 0x6d, 0x2c, 0xeb, 0x42, 0xad, 0x6e, 0x6d, 0xa8, 0x12, + 0x07, 0x76, 0xb2, 0xa8, 0x9c, 0xab, 0xf0, 0x9a, 0xb5, 0xa9, 0x98, 0xdd, + 0x1f, 0xb6, 0x32, 0x2c, 0xa5, 0x88, 0xa0, 0xe4, 0xb9, 0x98, 0x11, 0x5c, + 0xfe, 0x70, 0x28, 0xb9, 0xb7, 0xd4, 0x42, 0xcb, 0xe8, 0x77, 0x46, 0x7c, + 0x71, 0xb8, 0x4c, 0x04, 0xc2, 0x21, 0x24, 0x74, 0x2c, 0xdb, 0x6a, 0xde, + 0xa4, 0x88, 0x31, 0x69, 0x8e, 0x00, 0xc4, 0x1c, 0x59, 0x5f, 0x43, 0x83, + 0x37, 0xb7, 0x67, 0xf1, 0x70, 0x74, 0x75, 0x43, 0xb0, 0x2a, 0xd0, 0xc4, + 0xbb, 0x74, 0x8a, 0xf6, 0x35, 0x3d, 0x17, 0x86, 0xb0, 0x32, 0xf7, 0xe5, + 0xfb, 0xce, 0x54, 0xbc, 0xc5, 0xc1, 0xc3, 0x3b, 0x99, 0x71, 0x4f, 0x2f, + 0x88, 0x35, 0x69, 0x74, 0x7b, 0x1a, 0x78, 0x0a, 0xef, 0x11, 0x26, 0x7e, + 0x24, 0xb1, 0x5d, 0x19, 0xe1, 0x89, 0x92, 0xa2, 0x6b, 0x8f, 0x64, 0xc9, + 0xb7, 0x9b, 0xfd, 0xca, 0x2a, 0x74, 0x50, 0x0c, 0xc7, 0xe5, 0x70, 0xeb, + 0xcf, 0x53, 0x7b, 0x4b, 0x05, 0x3f, 0xa6, 0x17, 0xd7, 0xf7, 0xf6, 0xf6, + 0x3e, 0x3d, 0x14, 0xf7, 0x3c, 0x50, 0x50, 0x57, 0x27, 0xc0, 0xc3, 0xc3, + 0x4b, 0x1b, 0xb2, 0x6c, 0x80, 0x74, 0x2e, 0xba, 0x2c, 0x52, 0xb3, 0xba, + 0xe5, 0x88, 0xf4, 0x4e, 0x72, 0x27, 0xd4, 0x66, 0xda, 0x8f, 0x93, 0x30, + 0x21, 0x38, 0xd6, 0xdb, 0xc7, 0x2d, 0x9b, 0xdb, 0x7c, 0xaa, 0xe7, 0x1b, + 0x11, 0x88, 0x47, 0x48, 0x11, 0x97, 0xce, 0xf7, 0x26, 0x4a, 0xce, 0x8e, + 0x77, 0xf0, 0x11, 0x97, 0x89, 0x57, 0xc2, 0x6f, 0x81, 0x1c, 0x0f, 0x5b, + 0x45, 0x16, 0xee, 0x44, 0xe4, 0x60, 0xfe, 0xb7, 0x66, 0xcc, 0x6e, 0xf4, + 0xf8, 0x5c, 0xbb, 0xa6, 0xbc, 0x66, 0xc3, 0x01, 0x40, 0xaf, 0x81, 0x06, + 0x8b, 0xed, 0x2b, 0xb6, 0x5b, 0x1e, 0x1a, 0x39, 0x63, 0x76, 0xd5, 0x93, + 0xac, 0x9a, 0x1f, 0xee, 0x6f, 0x18, 0x8c, 0xe0, 0xab, 0xc1, 0x94, 0xa6, + 0xb6, 0x89, 0x93, 0x46, 0xfd, 0x47, 0xa8, 0x50, 0x19, 0xda, 0x24, 0x71, + 0x68, 0x24, 0xa9, 0x95, 0x46, 0xda, 0x15, 0xa0, 0xd7, 0xb6, 0x82, 0x9c, + 0xe7, 0xbb, 0xf9, 0xa8, 0x24, 0x91, 0xd6, 0x9e, 0x2c, 0x0a, 0x4f, 0x91, + 0xf0, 0xdb, 0xd3, 0xdc, 0x73, 0x11, 0x77, 0xb6, 0xba, 0xe1, 0xbb, 0xf8, + 0xf8, 0xf8, 0xd8, 0xb8, 0x38, 0x34, 0x69, 0x69, 0x69, 0xa4, 0x84, 0x37, + 0x09, 0xe0, 0xfd, 0xf7, 0xb2, 0xb2, 0x10, 0xbd, 0xe2, 0x60, 0xbd, 0xe2, + 0x96, 0x9c, 0x7f, 0x2c, 0xb7, 0x77, 0x77, 0xc4, 0x0c, 0x0c, 0xd1, 0x4e, + 0x6d, 0x77, 0x17, 0xe8, 0x1f, 0x6c, 0xa5, 0x30, 0x4a, 0x94, 0xb8, 0x35, + 0x67, 0xb9, 0xc6, 0xf7, 0xe8, 0xbb, 0x9f, 0x87, 0x59, 0xc4, 0xe4, 0x13, + 0x2a, 0xf5, 0x44, 0x80, 0x8e, 0xfa, 0xec, 0x48, 0x8f, 0x06, 0xab, 0x27, + 0x97, 0x83, 0xc1, 0xf9, 0xbe, 0x77, 0x5d, 0xfe, 0xcd, 0x77, 0x03, 0xbd, + 0xf8, 0x93, 0xe1, 0xd6, 0x81, 0xba, 0x20, 0x1c, 0x6c, 0x4b, 0xac, 0x7a, + 0xa7, 0x0e, 0x22, 0x7a, 0x31, 0xb2, 0x6a, 0x9b, 0xd1, 0xde, 0x66, 0xef, + 0x53, 0x73, 0xde, 0x1f, 0x4e, 0xfd, 0xf5, 0x3d, 0x16, 0xb2, 0xe5, 0xa6, + 0x2d, 0x9a, 0xba, 0xba, 0x53, 0x45, 0x1a, 0xe0, 0x4e, 0xa7, 0xc4, 0x8d, + 0xce, 0x16, 0x47, 0xc2, 0xbf, 0xb5, 0xdb, 0x71, 0xe2, 0xc7, 0x24, 0x68, + 0x4d, 0x69, 0xfe, 0x43, 0x62, 0x4a, 0x2d, 0x0b, 0xb8, 0xd0, 0xc1, 0x54, + 0x24, 0xba, 0x6f, 0xb3, 0x47, 0xf1, 0x57, 0x9a, 0x0e, 0x4e, 0x1c, 0xc9, + 0x65, 0x8b, 0x12, 0xa7, 0x43, 0x68, 0xae, 0x87, 0xe2, 0x23, 0xcc, 0xe1, + 0xc8, 0x31, 0xdb, 0x6f, 0xd8, 0xf8, 0x72, 0xe5, 0xa2, 0x91, 0xff, 0x7a, + 0x40, 0x41, 0xc3, 0xde, 0x87, 0x93, 0x93, 0x3a, 0xa8, 0xaf, 0x12, 0x50, + 0x49, 0xfa, 0x08, 0xf0, 0xbf, 0x78, 0x31, 0x4f, 0x1e, 0xa1, 0x98, 0x2b, + 0xab, 0xaf, 0x9f, 0x32, 0x2f, 0xa6, 0xf2, 0xcb, 0x68, 0x51, 0xcf, 0x0d, + 0x86, 0x92, 0x35, 0xce, 0x22, 0xf6, 0x69, 0x66, 0x48, 0xca, 0x44, 0x9d, + 0x67, 0xd4, 0x78, 0x90, 0x45, 0xbd, 0xf7, 0x2d, 0xb8, 0xa3, 0x6d, 0x95, + 0xe8, 0xe7, 0x8f, 0x37, 0x29, 0x04, 0xd5, 0x29, 0x10, 0x15, 0x4a, 0x96, + 0x0d, 0x6e, 0x7c, 0x5b, 0xb3, 0x89, 0x9f, 0x3f, 0xd7, 0xe5, 0x54, 0xb9, + 0xc2, 0xb3, 0x7b, 0x4e, 0xe4, 0x83, 0x39, 0x29, 0x4b, 0x57, 0x9a, 0x3d, + 0x72, 0x0c, 0x25, 0x2d, 0x85, 0x98, 0x52, 0x0d, 0x33, 0x5e, 0x70, 0x71, + 0x3d, 0x46, 0xfd, 0xae, 0x7a, 0x27, 0xdb, 0xbf, 0x50, 0x64, 0xeb, 0x7b, + 0xe9, 0xfb, 0x9a, 0x46, 0x7e, 0xaa, 0x17, 0x79, 0x6a, 0x5a, 0xa3, 0xb9, + 0xc9, 0x7e, 0x72, 0x28, 0xcd, 0xeb, 0x85, 0xf9, 0xe9, 0xad, 0x3a, 0x1a, + 0xd3, 0xec, 0xc7, 0xd3, 0x74, 0x97, 0x12, 0xbd, 0xf9, 0x1e, 0x42, 0x08, + 0xc2, 0x8d, 0x09, 0x40, 0x19, 0xa6, 0xda, 0x43, 0xc4, 0x42, 0x50, 0x3c, + 0x85, 0x60, 0xe4, 0x5f, 0xb7, 0x36, 0x6f, 0xed, 0x24, 0x7c, 0xe1, 0x1a, + 0xef, 0x66, 0xc1, 0x0d, 0x23, 0x95, 0xdd, 0x4b, 0x71, 0x99, 0xf9, 0xa2, + 0x6a, 0x43, 0x6b, 0x6b, 0x36, 0x06, 0xdf, 0x23, 0xd9, 0x99, 0x74, 0xb6, + 0x6f, 0x0d, 0x64, 0xac, 0xac, 0xac, 0x1c, 0xcf, 0x9e, 0xb9, 0x46, 0x85, + 0x60, 0xf2, 0x3c, 0x7e, 0x9c, 0xee, 0x63, 0x22, 0xdf, 0xf5, 0xf6, 0x3a, + 0xde, 0xf6, 0xa3, 0x58, 0x0f, 0x71, 0xb9, 0x79, 0x75, 0x7a, 0xe9, 0x5b, + 0x75, 0x69, 0xbc, 0x0a, 0x42, 0x17, 0x11, 0xcb, 0x05, 0x11, 0x6b, 0x2a, + 0x9f, 0xf3, 0xbd, 0xab, 0x0d, 0x2a, 0x5c, 0x48, 0xe9, 0x40, 0x55, 0xe4, + 0x1b, 0x69, 0xe3, 0x50, 0xc9, 0x50, 0xc3, 0x91, 0x4e, 0x4e, 0x99, 0x72, + 0xc6, 0x5a, 0xcb, 0xb1, 0x2c, 0xef, 0x72, 0x0a, 0x4a, 0xb3, 0xef, 0xf0, + 0xb4, 0x53, 0xef, 0x67, 0xf8, 0x77, 0xb7, 0xa6, 0xc6, 0xfb, 0xce, 0x7f, + 0x36, 0x31, 0x92, 0x96, 0xd1, 0x3c, 0xde, 0x6b, 0x9b, 0x78, 0x78, 0x08, + 0xd1, 0x11, 0x62, 0xb3, 0xbd, 0x4a, 0x73, 0x1b, 0x70, 0x19, 0x4e, 0x17, + 0xa7, 0xc4, 0xc5, 0xc5, 0xd5, 0x60, 0x4d, 0x5b, 0x97, 0x39, 0xda, 0xbb, + 0xbe, 0x36, 0xb3, 0x15, 0x53, 0x11, 0xfe, 0x1e, 0xac, 0xd1, 0x8c, 0xb5, + 0xd5, 0xe8, 0xfe, 0xaa, 0x8d, 0x51, 0x5c, 0x85, 0x59, 0x0b, 0x67, 0x87, + 0x00, 0x09, 0x6f, 0xae, 0xb3, 0x7f, 0xe1, 0xb1, 0xe7, 0xee, 0x17, 0x34, + 0x9c, 0xc2, 0x52, 0xac, 0x13, 0xf7, 0x5a, 0xf1, 0xe5, 0xdd, 0x8f, 0x2b, + 0x40, 0x19, 0x98, 0x9d, 0xfc, 0xb3, 0x7f, 0x97, 0x9c, 0x42, 0x17, 0x8d, + 0x7c, 0xa0, 0x22, 0x98, 0xc0, 0xc2, 0x93, 0x5b, 0xe1, 0xdb, 0x6a, 0xbc, + 0x5c, 0x0e, 0x60, 0x54, 0x51, 0x51, 0xa1, 0x14, 0x9b, 0x7c, 0x69, 0x67, + 0xf7, 0xf4, 0x77, 0x99, 0xc9, 0x5f, 0xad, 0x6f, 0xe3, 0x67, 0x06, 0x8f, + 0x2d, 0x3f, 0x58, 0x23, 0x91, 0x44, 0x28, 0xe1, 0x17, 0xe6, 0x5c, 0xbb, + 0x53, 0xa7, 0x93, 0x66, 0x1c, 0x02, 0x8e, 0x59, 0x47, 0xc2, 0xa6, 0x7a, + 0x19, 0x2b, 0x8f, 0x6f, 0x24, 0xb9, 0xec, 0x1f, 0x71, 0xab, 0xc4, 0xbd, + 0x9e, 0x77, 0x98, 0x2d, 0xd6, 0xd2, 0x9e, 0x17, 0x86, 0x18, 0x99, 0x2c, + 0xfe, 0xe6, 0x97, 0x6e, 0xdb, 0xa9, 0xc3, 0x97, 0x6b, 0xff, 0xf8, 0x8d, + 0x3f, 0xa2, 0x27, 0x88, 0x3d, 0xc3, 0x0b, 0xbd, 0x6a, 0xaf, 0xd5, 0xa6, + 0xb9, 0x7a, 0x7b, 0xdb, 0x56, 0x84, 0x6e, 0x78, 0x42, 0x3b, 0xb0, 0x32, + 0x50, 0x24, 0xa2, 0xe7, 0x38, 0xd3, 0x03, 0x73, 0x02, 0xc5, 0xfb, 0xa6, + 0xf2, 0x05, 0x11, 0x25, 0xf6, 0x3e, 0xf8, 0x6e, 0x1c, 0x10, 0x4c, 0x3d, + 0xda, 0x96, 0x27, 0xcc, 0xdd, 0xda, 0x22, 0x5b, 0xfa, 0x0d, 0x2e, 0xd8, + 0xf7, 0xa7, 0x3d, 0x97, 0x80, 0x7d, 0x47, 0x5e, 0x82, 0x80, 0x09, 0xeb, + 0x21, 0x63, 0x97, 0xfc, 0xe9, 0xef, 0x65, 0x4b, 0x9a, 0xdc, 0x43, 0xb2, + 0x13, 0x68, 0xc3, 0x03, 0xdf, 0xaa, 0xea, 0xeb, 0x45, 0x9a, 0x4f, 0x06, + 0x9f, 0xbf, 0x67, 0x48, 0x8e, 0x8d, 0x0d, 0xdc, 0xca, 0x0c, 0x58, 0x2a, + 0x54, 0xd0, 0x2e, 0xd4, 0x32, 0x39, 0xc5, 0x66, 0xba, 0x59, 0x7b, 0x20, + 0xdd, 0xee, 0x45, 0x6d, 0x47, 0x7c, 0x5e, 0x47, 0xbf, 0x24, 0x64, 0x54, + 0x31, 0x41, 0xd5, 0x3d, 0xe1, 0x73, 0x8d, 0x7a, 0xf4, 0xd6, 0xb8, 0x10, + 0xfa, 0x76, 0x47, 0xcf, 0x95, 0x8d, 0xcb, 0xdf, 0xe6, 0x3d, 0x94, 0xf3, + 0x86, 0x93, 0xb6, 0xbb, 0x98, 0x90, 0xbd, 0xd7, 0x71, 0x71, 0xf3, 0x66, + 0xfb, 0xf5, 0xc5, 0x56, 0xd3, 0xef, 0x6a, 0xb4, 0xfd, 0x89, 0x6c, 0xd7, + 0xbf, 0xaa, 0x26, 0x71, 0x1a, 0x04, 0x25, 0x9b, 0xf9, 0xcf, 0xe6, 0x63, + 0x12, 0x22, 0x0f, 0x1f, 0x5d, 0x2e, 0xc0, 0x47, 0x57, 0xaf, 0xff, 0x96, + 0x2b, 0xd9, 0xd9, 0x4d, 0xa4, 0x11, 0xc6, 0x97, 0xe8, 0x99, 0x9d, 0x46, + 0x4e, 0xf9, 0x08, 0x94, 0xaf, 0x5b, 0x9c, 0xbc, 0x9a, 0x7c, 0x1a, 0xed, + 0x15, 0x95, 0x93, 0xe3, 0x6e, 0xae, 0xfe, 0x02, 0xab, 0x22, 0x0a, 0x3d, + 0xb0, 0x03, 0xe3, 0xda, 0x62, 0x4c, 0xf7, 0xc7, 0x3d, 0x3a, 0x84, 0x7e, + 0x00, 0x32, 0xa4, 0x7f, 0x72, 0x58, 0x5e, 0xf1, 0x7e, 0x9a, 0x87, 0xcb, + 0xfe, 0xec, 0x69, 0x64, 0xf0, 0x42, 0xa7, 0x77, 0x47, 0x6b, 0x55, 0x15, + 0x91, 0xd8, 0x59, 0x9a, 0xc7, 0x07, 0x1f, 0x5d, 0xe7, 0x23, 0x7a, 0xda, + 0xfd, 0x8b, 0xb4, 0xe5, 0x01, 0x57, 0x13, 0x69, 0x50, 0x58, 0x54, 0x54, + 0x0f, 0xb0, 0x49, 0x8d, 0xb5, 0x05, 0x04, 0xe8, 0xbc, 0x79, 0x03, 0x9b, + 0xaf, 0x7d, 0x9f, 0x22, 0xf9, 0x41, 0xe8, 0x62, 0x6f, 0x76, 0xfd, 0xcb, + 0xb6, 0x20, 0xab, 0xd8, 0x62, 0x2c, 0x3b, 0xb0, 0x67, 0xd3, 0x8a, 0x09, + 0x30, 0x31, 0xbe, 0x7c, 0x01, 0x60, 0x2b, 0x67, 0x22, 0x2a, 0xc5, 0x8e, + 0x3f, 0x7d, 0x06, 0x0f, 0x74, 0x39, 0x5a, 0x8f, 0xc9, 0x33, 0xdc, 0xf0, + 0x66, 0x27, 0x16, 0xe7, 0x98, 0x5a, 0x57, 0xd0, 0xdd, 0xeb, 0x6e, 0x9d, + 0xa7, 0x62, 0x6b, 0xec, 0x98, 0x42, 0x70, 0x97, 0x80, 0xc9, 0x4d, 0x22, + 0xf6, 0xcd, 0xea, 0xc0, 0xdf, 0xcb, 0xfd, 0x9b, 0xe6, 0xca, 0x8a, 0xa3, + 0x21, 0x2e, 0x8f, 0x0f, 0xc7, 0xef, 0xdf, 0x1f, 0x16, 0x16, 0x59, 0x94, + 0xf4, 0xd1, 0x8c, 0xb8, 0x97, 0xa3, 0xcd, 0x96, 0x62, 0xe7, 0x90, 0xd6, + 0xa1, 0xf4, 0x24, 0x29, 0x26, 0x53, 0x39, 0x55, 0x45, 0x68, 0xc8, 0x19, + 0x4e, 0x7b, 0xcc, 0xbb, 0x64, 0x19, 0xd6, 0xf1, 0x4f, 0x2c, 0x72, 0x65, + 0x3a, 0xb2, 0x2e, 0xa2, 0x9b, 0xcd, 0x27, 0x7c, 0xae, 0x27, 0xe1, 0x26, + 0x83, 0xd4, 0x13, 0x94, 0x8f, 0x1e, 0xa9, 0xa7, 0x41, 0x75, 0x6b, 0xb8, + 0x56, 0xd1, 0x43, 0x3d, 0xbe, 0x7f, 0xff, 0x6e, 0x5f, 0x99, 0x65, 0x3e, + 0xb9, 0xfc, 0xbe, 0xb6, 0x33, 0x18, 0xf9, 0x55, 0x0e, 0xf9, 0xf7, 0x51, + 0x87, 0xb4, 0x69, 0xd2, 0x3f, 0x9a, 0xf6, 0x07, 0x38, 0x53, 0x5b, 0xeb, + 0x8b, 0xff, 0x9d, 0xef, 0x53, 0xfe, 0x62, 0xc0, 0xfc, 0x39, 0x8d, 0xd6, + 0x1e, 0x24, 0x7a, 0xf9, 0xf6, 0x82, 0x5e, 0x58, 0x16, 0xbc, 0xfd, 0x3a, + 0x31, 0xf6, 0xe2, 0x19, 0x77, 0x71, 0xe7, 0x3a, 0x4f, 0x4b, 0x4c, 0x73, + 0xe7, 0x2f, 0x0a, 0xc1, 0x34, 0x85, 0x28, 0xeb, 0x5b, 0x81, 0x08, 0xab, + 0x80, 0xca, 0x79, 0x0c, 0x49, 0xdb, 0xed, 0xb1, 0x37, 0x6e, 0x76, 0x76, + 0x0f, 0xf4, 0x5b, 0xce, 0x93, 0x34, 0x68, 0x32, 0xc5, 0xf4, 0xb1, 0x05, + 0x13, 0x92, 0xfe, 0x39, 0x55, 0x27, 0x06, 0xbb, 0x57, 0xbf, 0x35, 0xce, + 0xb8, 0x54, 0x9a, 0xa3, 0x39, 0xb0, 0xde, 0x3b, 0x8b, 0x3c, 0x3b, 0x74, + 0x9a, 0xf3, 0xbf, 0x88, 0x4b, 0xf5, 0xba, 0x5d, 0x2a, 0x54, 0x0d, 0x51, + 0x50, 0x4e, 0xd6, 0x35, 0x31, 0x8a, 0x61, 0xa7, 0xf0, 0x0f, 0x3b, 0xfb, + 0x99, 0xe4, 0x37, 0x28, 0x40, 0x6d, 0x7f, 0x7e, 0xd5, 0x54, 0xf2, 0xfb, + 0xae, 0x80, 0x1c, 0x37, 0xd2, 0x4d, 0x64, 0x77, 0x43, 0xa3, 0x99, 0x10, + 0x26, 0x9b, 0x29, 0xea, 0xd4, 0xd7, 0x9d, 0xde, 0x3c, 0x56, 0x86, 0x88, + 0x15, 0x22, 0x4b, 0xd2, 0x5b, 0x1b, 0xf7, 0x1e, 0x32, 0x64, 0x83, 0x73, + 0xab, 0x64, 0xdf, 0xdc, 0xdd, 0x39, 0x51, 0x29, 0x0d, 0x2c, 0xd4, 0xa1, + 0xe0, 0xd8, 0x37, 0xea, 0xd4, 0x3e, 0x1a, 0x28, 0x54, 0x66, 0xd7, 0x94, + 0x55, 0x4f, 0x87, 0x9c, 0xf8, 0xa3, 0x89, 0x30, 0x8e, 0x0e, 0x8a, 0xc7, + 0x93, 0xa8, 0x5c, 0xc1, 0xb0, 0x6c, 0x2c, 0x31, 0xed, 0xaf, 0x67, 0x3a, + 0xbb, 0xb5, 0x71, 0x3e, 0x42, 0x18, 0xbd, 0xb3, 0xbf, 0xf8, 0xf5, 0x4c, + 0x59, 0x2a, 0xc4, 0x87, 0x96, 0xb8, 0x1c, 0x26, 0x64, 0x23, 0x47, 0x86, + 0x71, 0x8e, 0x14, 0x56, 0xc7, 0x0c, 0xc4, 0xaa, 0xc6, 0x84, 0x29, 0x11, + 0x2a, 0x7a, 0x71, 0x0c, 0xef, 0x6b, 0xf4, 0xe7, 0x8b, 0x7c, 0x35, 0x0a, + 0x13, 0x8d, 0xb8, 0x27, 0xfa, 0xf7, 0xd2, 0x4a, 0x23, 0x3f, 0xc8, 0x04, + 0xdc, 0x49, 0x31, 0xe8, 0x3a, 0x30, 0x7f, 0x7e, 0x5e, 0xb0, 0x1d, 0xd0, + 0x2f, 0x15, 0x66, 0xb8, 0xdd, 0xad, 0xf6, 0xcf, 0x8f, 0x88, 0x97, 0x10, + 0x99, 0x39, 0xbe, 0x9b, 0xa0, 0x47, 0x6a, 0x0e, 0x96, 0x5b, 0x50, 0xd1, + 0x18, 0xed, 0x5d, 0xe7, 0x69, 0x8d, 0x09, 0x5a, 0x73, 0x2d, 0xd0, 0x2a, + 0x54, 0x20, 0xbb, 0x19, 0x89, 0xdd, 0xc8, 0xb9, 0x24, 0xc3, 0x8f, 0xf4, + 0xa2, 0x03, 0x14, 0x7b, 0x22, 0x5d, 0x74, 0x09, 0xa7, 0x4c, 0xe2, 0xfc, + 0x0f, 0x3f, 0x89, 0x73, 0x02, 0xd5, 0xa1, 0xe2, 0x2f, 0x04, 0x9f, 0xc1, + 0xe5, 0xbd, 0xa2, 0x7d, 0xb5, 0x8b, 0x4a, 0x47, 0x57, 0x11, 0x87, 0xb9, + 0x45, 0xdf, 0x46, 0x0a, 0x15, 0x93, 0xa9, 0xc9, 0x04, 0xbc, 0xe3, 0xbb, + 0xe2, 0x4e, 0x13, 0x2c, 0x3a, 0xe2, 0x34, 0x64, 0x63, 0x16, 0x3e, 0x53, + 0x92, 0x32, 0x60, 0xfe, 0xe1, 0x05, 0xc5, 0x5a, 0x11, 0xca, 0x82, 0x9d, + 0xef, 0x6a, 0xe4, 0xbf, 0x10, 0x86, 0x83, 0xcb, 0xd7, 0x9d, 0xfb, 0xf5, + 0x9b, 0x36, 0x6c, 0x9a, 0x9b, 0xd6, 0xde, 0xcd, 0xec, 0x8f, 0xe0, 0xa7, + 0x5d, 0xed, 0x5f, 0x9e, 0x36, 0x59, 0x19, 0xba, 0x9f, 0x47, 0x73, 0x62, + 0x76, 0x31, 0xa7, 0x23, 0x00, 0xef, 0x9e, 0xab, 0xfc, 0x0a, 0x84, 0x04, + 0x76, 0xb1, 0x7e, 0x08, 0xf8, 0xb7, 0xef, 0x98, 0x37, 0xf6, 0xcc, 0x01, + 0x51, 0xaf, 0xac, 0x2e, 0xfa, 0x29, 0x34, 0xd3, 0x2c, 0x3c, 0x46, 0x7a, + 0x7e, 0xf7, 0x47, 0x78, 0x6a, 0xff, 0x4b, 0xbe, 0xb5, 0xc7, 0xb9, 0xc7, + 0x85, 0x4f, 0x6b, 0x6a, 0xa4, 0xdd, 0xae, 0xa9, 0xe0, 0x39, 0x04, 0x80, + 0x82, 0x2b, 0x67, 0xc6, 0xf1, 0x2b, 0xc7, 0x1c, 0x0c, 0xf8, 0xb3, 0x40, + 0xb2, 0x6d, 0xcc, 0x0d, 0x8f, 0x0e, 0x2f, 0x32, 0x54, 0x6f, 0xd9, 0x11, + 0xcb, 0x97, 0x63, 0xee, 0x2e, 0xf6, 0xad, 0x79, 0xcf, 0x48, 0xc1, 0x69, + 0x12, 0x15, 0xcf, 0xbf, 0x35, 0x0d, 0x0d, 0x32, 0x29, 0x67, 0xbc, 0x27, + 0x2a, 0x16, 0x84, 0x15, 0x4e, 0xf9, 0xc4, 0xb2, 0xd9, 0xed, 0x28, 0xb2, + 0xe4, 0x63, 0x30, 0x75, 0xa7, 0xaa, 0x0a, 0x9a, 0x87, 0x0f, 0x27, 0xd5, + 0xd0, 0xc7, 0xea, 0x1e, 0xec, 0x12, 0xf5, 0xb2, 0x33, 0xb7, 0xd5, 0x13, + 0x10, 0xbf, 0x85, 0x1c, 0x14, 0xe1, 0x1e, 0x7b, 0x23, 0xe1, 0xdd, 0xdd, + 0xac, 0xb0, 0xe1, 0x6f, 0x99, 0xce, 0x12, 0xe7, 0x25, 0x6a, 0xf4, 0xb0, + 0x39, 0xad, 0x9a, 0xeb, 0xb4, 0xd9, 0xc7, 0x8f, 0x55, 0x6e, 0xbe, 0x7c, + 0x8e, 0xe6, 0xf8, 0x0c, 0xf8, 0xfc, 0x8e, 0x80, 0xfe, 0xba, 0x56, 0xc7, + 0xf0, 0x7a, 0x62, 0x1a, 0x69, 0x74, 0x2d, 0x90, 0xc8, 0xd7, 0x9b, 0x35, + 0x65, 0xff, 0xb6, 0x6e, 0x1e, 0x0d, 0x19, 0x90, 0x5c, 0x36, 0x61, 0xcf, + 0x7b, 0x50, 0xf7, 0x89, 0x3c, 0x22, 0x01, 0x9c, 0xaf, 0xf3, 0x7b, 0xf2, + 0xed, 0x4e, 0x78, 0xf9, 0xf1, 0x78, 0xda, 0x43, 0xf6, 0xf7, 0x49, 0x77, + 0x2a, 0x51, 0x58, 0xaf, 0x97, 0x0a, 0x0d, 0xef, 0x94, 0xbd, 0x64, 0xdc, + 0x77, 0x4d, 0x2f, 0x85, 0xb7, 0x67, 0x84, 0xe9, 0x5e, 0x51, 0x67, 0x67, + 0xe4, 0xd5, 0x96, 0x0d, 0x17, 0x73, 0xdf, 0xf6, 0x2b, 0x2a, 0x78, 0x15, + 0x94, 0x94, 0x72, 0x1b, 0x1b, 0x69, 0xaa, 0xad, 0x87, 0xed, 0x97, 0x9c, + 0xfa, 0x96, 0x98, 0x2b, 0xf4, 0x4b, 0xc2, 0xbb, 0x95, 0xc3, 0xb4, 0x08, + 0x19, 0xd4, 0x3a, 0x4a, 0x44, 0xcb, 0xd7, 0xe7, 0xd3, 0x43, 0x57, 0xc4, + 0x46, 0xe3, 0x39, 0xd4, 0xb4, 0x66, 0xd2, 0xc2, 0xc2, 0xb6, 0x1c, 0x6b, + 0x67, 0x35, 0xac, 0x9f, 0x91, 0x33, 0x42, 0x19, 0x86, 0x01, 0x00, 0x2a, + 0x7c, 0x69, 0xd7, 0x77, 0x91, 0xd8, 0xfa, 0x06, 0x05, 0xf1, 0x5a, 0x0d, + 0x92, 0xa1, 0x5e, 0x42, 0x85, 0xba, 0x59, 0x34, 0x70, 0x61, 0xc1, 0x38, + 0x92, 0x4e, 0x94, 0x44, 0x57, 0x77, 0x6b, 0x99, 0x5c, 0xea, 0x21, 0xd9, + 0xe0, 0x6a, 0x82, 0x91, 0xed, 0x39, 0x25, 0x37, 0x24, 0xbd, 0xfb, 0xc0, + 0x79, 0xe5, 0xf4, 0x61, 0xbf, 0xf3, 0xc4, 0x7d, 0x59, 0x2e, 0xc9, 0x64, + 0xeb, 0x13, 0xf1, 0xa3, 0x07, 0x33, 0x2a, 0xfc, 0xaf, 0xeb, 0xce, 0x96, + 0x2c, 0x4f, 0xc9, 0x18, 0x8e, 0x9f, 0xfc, 0x77, 0xd2, 0x80, 0x28, 0xce, + 0x88, 0xdd, 0x28, 0xd1, 0x05, 0x81, 0xc9, 0xc9, 0x83, 0xaf, 0xae, 0xbc, + 0x1e, 0x61, 0x63, 0x37, 0xed, 0x9d, 0x76, 0x11, 0x49, 0x9b, 0xf7, 0x46, + 0x52, 0x83, 0x02, 0x57, 0x64, 0x02, 0xf6, 0xf4, 0x6f, 0x28, 0x04, 0xec, + 0xeb, 0xca, 0xe7, 0x70, 0x77, 0x4e, 0x44, 0xb6, 0xc2, 0xc4, 0xe3, 0xa2, + 0xad, 0x32, 0xfd, 0xd7, 0xad, 0xdf, 0x92, 0x0f, 0x7c, 0xd3, 0x0a, 0xe6, + 0xa9, 0x9e, 0xed, 0xee, 0x91, 0x11, 0x72, 0xf7, 0x65, 0x06, 0x6d, 0xd3, + 0x03, 0x0a, 0xb1, 0xe5, 0xc3, 0xf2, 0x72, 0x6e, 0xd9, 0xc1, 0x0c, 0xe1, + 0xc8, 0x7b, 0x1a, 0x10, 0xea, 0xd5, 0x69, 0xbc, 0xae, 0x7f, 0xfa, 0xf5, + 0x6e, 0x1e, 0xd3, 0x08, 0xe0, 0x18, 0x18, 0x18, 0x28, 0xab, 0xaa, 0x06, + 0x0d, 0x38, 0xc8, 0xb6, 0x85, 0xf1, 0x1a, 0x4f, 0xb4, 0xbd, 0x2e, 0xbe, + 0xc3, 0xd9, 0xd9, 0x2d, 0xb2, 0xdf, 0xad, 0xb4, 0x9d, 0xb5, 0xb9, 0x9a, + 0x6e, 0x2c, 0xe5, 0x28, 0x2f, 0xb1, 0x83, 0x16, 0x8b, 0x16, 0x6b, 0x3d, + 0x6e, 0x5c, 0xb4, 0x16, 0xbf, 0xc1, 0xd4, 0x7c, 0xa9, 0x5d, 0x1f, 0x6f, + 0x3d, 0x09, 0xc8, 0x73, 0x52, 0x44, 0xac, 0x41, 0x95, 0xf1, 0xc5, 0x63, + 0xd0, 0xcf, 0xd4, 0x17, 0xd8, 0x99, 0xbe, 0x27, 0x03, 0x98, 0x97, 0xef, + 0x6d, 0x6d, 0x51, 0x77, 0x4f, 0xc7, 0x02, 0xcc, 0x0d, 0xf8, 0xe8, 0x60, + 0x72, 0x4e, 0x73, 0x1b, 0x75, 0xad, 0x11, 0x91, 0x08, 0x7e, 0xbd, 0x86, + 0x84, 0x5d, 0x66, 0xaf, 0x7b, 0x39, 0x6d, 0xb0, 0x91, 0x25, 0xd7, 0x18, + 0x8b, 0x07, 0xbb, 0xc8, 0xe2, 0x2c, 0x32, 0xe1, 0x40, 0x47, 0x67, 0xf6, + 0x95, 0x6c, 0xe7, 0x14, 0x7e, 0xe1, 0xa1, 0xa4, 0x19, 0x74, 0x4f, 0x70, + 0x62, 0x95, 0x63, 0x8e, 0x86, 0x86, 0x26, 0xbc, 0xa4, 0x84, 0x73, 0xfb, + 0xfc, 0x3d, 0xfb, 0x36, 0xa0, 0xcb, 0x22, 0x19, 0x24, 0x69, 0x40, 0x47, + 0x63, 0x8b, 0x09, 0x7c, 0x87, 0x9f, 0x0d, 0xde, 0x1f, 0xbc, 0x56, 0x7e, + 0x13, 0x9b, 0xfe, 0x06, 0x61, 0x95, 0xe9, 0xa8, 0xe8, 0x60, 0xec, 0x5a, + 0x2c, 0x26, 0xcb, 0xfb, 0xed, 0x9d, 0x00, 0x46, 0x86, 0x70, 0x6a, 0x7c, + 0xed, 0x73, 0x30, 0xcd, 0xce, 0x13, 0x5b, 0x3a, 0x31, 0x28, 0xb2, 0x2b, + 0x5b, 0xed, 0x51, 0xe0, 0xd8, 0xd8, 0x58, 0x04, 0x1b, 0x7c, 0xe5, 0x36, + 0xd7, 0x53, 0x25, 0xde, 0xbc, 0x6e, 0xbe, 0x72, 0x75, 0x7e, 0x91, 0x4a, + 0xf8, 0x84, 0x46, 0x9d, 0x4a, 0x7c, 0x61, 0xdd, 0x85, 0x64, 0x0d, 0x17, + 0x10, 0xbf, 0x57, 0x87, 0xd3, 0xd2, 0x6b, 0x7d, 0x7e, 0x2e, 0x15, 0xe2, + 0x74, 0x5c, 0xf6, 0x53, 0xd6, 0x32, 0x6d, 0xed, 0xb6, 0xcd, 0x17, 0xd2, + 0x82, 0x82, 0x1f, 0x6c, 0x6d, 0xb1, 0xed, 0x48, 0x6b, 0x00, 0x95, 0xc9, + 0x62, 0xd7, 0x4e, 0xd5, 0x74, 0xe7, 0x80, 0xd4, 0x28, 0x90, 0x37, 0x30, + 0x98, 0x65, 0x65, 0x3d, 0xef, 0xf8, 0x84, 0xcd, 0x0c, 0x48, 0x10, 0x10, + 0x98, 0x82, 0x04, 0x51, 0x9e, 0xcc, 0x23, 0x97, 0xd5, 0x36, 0x3e, 0x91, + 0x4d, 0xf2, 0xeb, 0xed, 0xe0, 0xf3, 0x77, 0x47, 0x07, 0x45, 0x4e, 0x15, + 0xe2, 0x17, 0x54, 0x7b, 0xd1, 0xbf, 0xef, 0xe6, 0x1e, 0x75, 0xa4, 0x0c, + 0x36, 0x3c, 0xb4, 0x20, 0x29, 0x7f, 0x38, 0x56, 0x91, 0xae, 0x61, 0x45, + 0xc9, 0xb3, 0x87, 0xe3, 0xe3, 0xd4, 0x73, 0x91, 0x6a, 0x7e, 0x55, 0x67, + 0x23, 0x45, 0x5d, 0x61, 0x91, 0x92, 0x92, 0x22, 0x74, 0x19, 0x13, 0x11, + 0x21, 0xaf, 0x31, 0x52, 0x0e, 0x6f, 0xa4, 0x4c, 0xd6, 0x5d, 0x1b, 0x3d, + 0x4d, 0x82, 0x70, 0x9d, 0x22, 0x0b, 0xe4, 0x59, 0xff, 0x84, 0x0b, 0xda, + 0x4b, 0x74, 0x83, 0x40, 0xc4, 0x43, 0xa8, 0xef, 0x02, 0xe8, 0x4e, 0xff, + 0x5e, 0xcf, 0x15, 0x7c, 0xe8, 0x3a, 0x7c, 0xb8, 0x7e, 0xad, 0x70, 0x18, + 0x03, 0x4f, 0xf8, 0xc9, 0x5a, 0xcc, 0xa1, 0xc8, 0x3d, 0x6e, 0x8b, 0x15, + 0x93, 0x63, 0xa9, 0xc1, 0x8d, 0x0d, 0x34, 0x8a, 0xe1, 0x2f, 0x52, 0xd7, + 0x5e, 0xe5, 0xcc, 0x34, 0x25, 0x9d, 0xce, 0xd9, 0x89, 0x8a, 0xce, 0xea, + 0xb7, 0xf9, 0x4b, 0xda, 0xdb, 0xdb, 0xaf, 0x1c, 0x1e, 0x12, 0x45, 0xf4, + 0xa0, 0x1b, 0x24, 0x41, 0x54, 0x48, 0x44, 0xfe, 0xbb, 0xde, 0x1f, 0xd5, + 0xd3, 0xea, 0x73, 0x52, 0x24, 0xc3, 0x75, 0xa6, 0x26, 0xb3, 0x73, 0x8a, + 0x28, 0xea, 0x5e, 0xd3, 0xe5, 0x8e, 0x15, 0x30, 0xe5, 0xbd, 0x7f, 0xa5, + 0x5d, 0x7b, 0xff, 0x7e, 0xfc, 0x61, 0xd5, 0x79, 0xed, 0xa9, 0xfe, 0xfb, + 0x0b, 0xbd, 0x9b, 0x30, 0x0b, 0x19, 0x3a, 0xb0, 0xc8, 0xab, 0xa4, 0xd3, + 0xb6, 0xda, 0x79, 0x7c, 0x43, 0xa9, 0x00, 0xf6, 0xbc, 0x57, 0x67, 0xfd, + 0xe9, 0x5e, 0xc1, 0xd0, 0xdc, 0x8b, 0x8a, 0x3f, 0x7f, 0xfa, 0xcc, 0x6a, + 0x80, 0x0e, 0x11, 0x93, 0xae, 0x34, 0x83, 0x6e, 0xe7, 0xdc, 0x87, 0xb7, + 0x57, 0xd3, 0xcc, 0x2c, 0xa0, 0x03, 0x4e, 0x75, 0x2e, 0xe6, 0xf0, 0xb0, + 0xf7, 0xea, 0xd1, 0x15, 0xb5, 0x04, 0xcd, 0x73, 0x48, 0x72, 0x71, 0x87, + 0x65, 0xc7, 0x7c, 0xa6, 0x43, 0x37, 0xd1, 0x87, 0xe8, 0x40, 0xb8, 0x27, + 0xf3, 0xf0, 0x19, 0x66, 0x10, 0xf8, 0xa4, 0xa4, 0xed, 0x61, 0xca, 0xa8, + 0xb8, 0xc8, 0x63, 0x5c, 0x53, 0xe0, 0x17, 0x37, 0x0a, 0xea, 0xc4, 0x88, + 0x30, 0xf1, 0xc0, 0xa2, 0xf3, 0x2a, 0x63, 0xc6, 0xc9, 0x8c, 0x75, 0x9b, + 0x65, 0x6f, 0x52, 0x8a, 0x91, 0x06, 0xa2, 0xc8, 0xf1, 0x4c, 0x21, 0x68, + 0x86, 0x7c, 0x52, 0xa5, 0xe0, 0x35, 0x93, 0xd4, 0x62, 0x7d, 0xd7, 0x30, + 0xaf, 0x00, 0x08, 0xfc, 0x2a, 0x87, 0xaa, 0xfe, 0x97, 0x2d, 0xf2, 0x4c, + 0xd1, 0xfd, 0xfc, 0x5b, 0xb8, 0x06, 0x51, 0xec, 0x15, 0xd9, 0xf5, 0x6f, + 0x66, 0x53, 0x76, 0xde, 0x23, 0x62, 0xf9, 0xf7, 0xef, 0xcf, 0x72, 0xab, + 0x8c, 0x4f, 0x95, 0x46, 0xe8, 0x73, 0xd1, 0x42, 0xa1, 0xe0, 0x1f, 0xec, + 0xa2, 0xd3, 0x25, 0x30, 0xf5, 0xc4, 0x27, 0x43, 0xd6, 0xd5, 0x4c, 0xb6, + 0x04, 0x55, 0xc6, 0xb4, 0x78, 0xa0, 0xa0, 0xac, 0x74, 0xae, 0x21, 0xf2, + 0x89, 0xb4, 0xe8, 0xb6, 0x87, 0x32, 0x23, 0xbe, 0x87, 0xf2, 0x4b, 0x19, + 0xf0, 0xf6, 0xe8, 0x57, 0x8e, 0x82, 0x92, 0x2a, 0x9a, 0x72, 0xbf, 0x1f, + 0x4b, 0xfb, 0xc0, 0x0c, 0xe6, 0x3f, 0x9d, 0x0d, 0xc9, 0x3e, 0x2c, 0xdb, + 0xd4, 0x4d, 0xfc, 0x28, 0xcd, 0x83, 0x8d, 0x09, 0x33, 0x1c, 0xdb, 0x63, + 0x75, 0x0d, 0xc7, 0xf7, 0x68, 0x3d, 0x7b, 0x4c, 0x2f, 0xb6, 0xec, 0xbb, + 0xd6, 0x9d, 0xb9, 0x78, 0xf0, 0xc2, 0x79, 0x85, 0xd6, 0xc2, 0x7a, 0x13, + 0xdb, 0x6c, 0xc0, 0xd5, 0xea, 0x34, 0xf0, 0x6c, 0x7a, 0x53, 0x2a, 0x32, + 0xb5, 0x6e, 0x71, 0xc6, 0xe0, 0x2d, 0xc9, 0xaf, 0x92, 0xb2, 0x25, 0xc4, + 0xa8, 0x90, 0xd2, 0x7a, 0xf1, 0xe1, 0x65, 0xf6, 0x92, 0xa5, 0x23, 0x74, + 0xc8, 0xb2, 0xbd, 0x5e, 0x3e, 0x1f, 0xef, 0x4a, 0x2b, 0x7f, 0xb7, 0x3a, + 0x3f, 0x7b, 0xb5, 0xe2, 0x55, 0x1c, 0xd3, 0x67, 0xd4, 0xe3, 0x33, 0x5f, + 0x39, 0xe5, 0xfe, 0xc9, 0xd8, 0xaa, 0x2a, 0xc9, 0x3e, 0xd0, 0x3b, 0x16, + 0xd0, 0xf6, 0x0f, 0x9a, 0x12, 0x9f, 0x0f, 0xdc, 0x21, 0x66, 0xf0, 0xc4, + 0x5f, 0xd9, 0x71, 0x8e, 0x81, 0xf0, 0x68, 0xe6, 0xbe, 0xd7, 0xeb, 0x4d, + 0x99, 0x44, 0xab, 0x63, 0x95, 0x3a, 0x3a, 0xd3, 0xb5, 0x07, 0x7f, 0x21, + 0x38, 0xbd, 0x4f, 0x64, 0x71, 0x7c, 0x07, 0x1d, 0x47, 0xe7, 0x8b, 0x64, + 0xc2, 0xf2, 0x68, 0x01, 0xd1, 0xe6, 0x1b, 0xa2, 0x27, 0xbe, 0x26, 0x14, + 0xc1, 0xba, 0x8f, 0x3d, 0xc2, 0xf5, 0x0c, 0xb4, 0x3d, 0xcb, 0x0c, 0xfa, + 0x7a, 0x7f, 0x87, 0x17, 0x84, 0x6e, 0xeb, 0x2b, 0x76, 0x8c, 0x1c, 0xdc, + 0x3d, 0x7d, 0xf7, 0xe5, 0xe1, 0x87, 0xf4, 0x01, 0xd0, 0x2e, 0x0c, 0x61, + 0xca, 0xb6, 0x19, 0x17, 0xb7, 0xdc, 0x2c, 0x86, 0x84, 0x3c, 0x08, 0xb9, + 0xd9, 0x3b, 0xe7, 0x19, 0x65, 0xbf, 0x7d, 0xd7, 0x6d, 0x33, 0xb3, 0xdf, + 0x63, 0x73, 0x77, 0xdb, 0x9b, 0x37, 0xe3, 0x60, 0xe5, 0x89, 0x41, 0x58, + 0xd9, 0x61, 0x29, 0xfb, 0xca, 0x04, 0xc3, 0x91, 0x46, 0x18, 0x29, 0x36, + 0x10, 0x47, 0xf8, 0xc6, 0x10, 0x1a, 0x25, 0xf8, 0xd5, 0xbf, 0xb3, 0x98, + 0xb1, 0x44, 0x5e, 0xd5, 0xa7, 0xf6, 0xab, 0xe4, 0xe4, 0x96, 0x02, 0xdf, + 0x9f, 0x4c, 0xfb, 0x73, 0x5d, 0xa2, 0xd9, 0x7d, 0x83, 0x26, 0x87, 0x5a, + 0x05, 0x9f, 0x66, 0x0d, 0x89, 0xf0, 0xd6, 0x8d, 0xb0, 0x51, 0xe2, 0x9e, + 0xa3, 0x1b, 0xba, 0xe8, 0x9c, 0xc7, 0x20, 0x1b, 0x50, 0xc5, 0x4a, 0xe1, + 0x8d, 0xf3, 0x72, 0xba, 0xf0, 0x73, 0x3a, 0xf2, 0x63, 0x4c, 0x24, 0x3c, + 0xcf, 0x66, 0x03, 0x76, 0x1a, 0x8d, 0x31, 0xd3, 0x7a, 0xc9, 0x41, 0x63, + 0xd8, 0xc2, 0x8c, 0x0d, 0xd2, 0x8d, 0x62, 0x7a, 0xe4, 0x4b, 0x43, 0x26, + 0x60, 0x6f, 0xe7, 0xfd, 0x6f, 0x34, 0x3f, 0x9d, 0x81, 0x65, 0xa7, 0x16, + 0x90, 0x27, 0x99, 0x2c, 0x38, 0x92, 0xd2, 0x49, 0x1b, 0xbf, 0x6c, 0xd0, + 0x64, 0xc8, 0x30, 0x9b, 0xef, 0x6f, 0x73, 0xeb, 0xd7, 0x93, 0xfe, 0x7e, + 0x21, 0x8c, 0x70, 0x83, 0x9e, 0x3f, 0xb6, 0xa6, 0x0b, 0x13, 0xff, 0x7c, + 0xe8, 0xc1, 0xd0, 0x19, 0xb7, 0x5e, 0xb0, 0xe2, 0xc1, 0x21, 0xaa, 0xd3, + 0x10, 0x04, 0xbe, 0x62, 0x54, 0xd9, 0x6d, 0xf8, 0x65, 0xff, 0xca, 0x5d, + 0x58, 0x31, 0x0a, 0x8c, 0x7a, 0x22, 0xe0, 0xab, 0xf3, 0x85, 0x05, 0xc7, + 0x2a, 0xd4, 0xaa, 0xc1, 0x51, 0x00, 0xa4, 0x1c, 0x1f, 0x26, 0x78, 0x38, + 0xd2, 0x15, 0xd6, 0x31, 0xa9, 0x12, 0x6d, 0x4c, 0x03, 0x28, 0xfe, 0x6d, + 0x8c, 0xe3, 0x99, 0xca, 0x4b, 0x0e, 0x12, 0xed, 0x91, 0x76, 0x87, 0x86, + 0xb1, 0x39, 0x0e, 0xad, 0x16, 0xa6, 0x47, 0x7e, 0xdf, 0x27, 0x4c, 0x1e, + 0xa0, 0x7e, 0x77, 0x97, 0x1b, 0xe9, 0x34, 0x2c, 0x10, 0x0d, 0x94, 0x0f, + 0x3d, 0xfa, 0x57, 0x4c, 0xbd, 0xf6, 0x24, 0x96, 0x0d, 0x4b, 0x38, 0xa0, + 0x7b, 0x7f, 0x2c, 0xdf, 0xab, 0x41, 0xba, 0x48, 0x06, 0x21, 0xcd, 0x9d, + 0xb1, 0x30, 0xca, 0xe7, 0x9c, 0x85, 0xed, 0x49, 0x99, 0x16, 0x47, 0xeb, + 0xad, 0x22, 0x7f, 0x28, 0x13, 0x6b, 0x2a, 0x0b, 0x98, 0xd4, 0xb4, 0x34, + 0x39, 0xb7, 0x56, 0x03, 0xdc, 0x45, 0xe2, 0x27, 0xc4, 0xb8, 0x64, 0xe4, + 0xb8, 0x51, 0xa7, 0x7e, 0x76, 0xcf, 0xa6, 0x2a, 0xde, 0xed, 0x5f, 0xfc, + 0xe4, 0x42, 0x0a, 0x2b, 0xa0, 0x6d, 0x85, 0x56, 0x73, 0x05, 0xdc, 0x51, + 0x03, 0x16, 0x94, 0x57, 0xfb, 0xc3, 0xea, 0x44, 0x13, 0xb4, 0x03, 0x13, + 0x69, 0x6b, 0x61, 0x0f, 0xab, 0x2c, 0x75, 0xa7, 0x25, 0x0f, 0xe1, 0x2e, + 0x50, 0x82, 0x05, 0xcc, 0xb3, 0x7f, 0xa1, 0x5d, 0x2e, 0xfc, 0xf9, 0x13, + 0xe8, 0x2c, 0x7f, 0x9e, 0xa0, 0x3c, 0x28, 0x98, 0xba, 0xe7, 0xeb, 0xb7, + 0x8e, 0x30, 0x58, 0x77, 0xfe, 0xf2, 0xf3, 0x11, 0x28, 0x20, 0x97, 0xc1, + 0xec, 0x7e, 0x59, 0xee, 0xec, 0xf1, 0x61, 0xa1, 0x9b, 0xad, 0xc2, 0x5b, + 0x24, 0xdc, 0x72, 0x8b, 0x12, 0xb6, 0x91, 0x3c, 0x7f, 0x0c, 0xdf, 0xe3, + 0x13, 0x59, 0xe0, 0x84, 0xcd, 0x21, 0xf8, 0xde, 0x3f, 0xde, 0xfa, 0x85, + 0x97, 0x58, 0x34, 0xca, 0xf6, 0x75, 0xff, 0xac, 0x52, 0x83, 0x20, 0x21, + 0x56, 0x4d, 0x0e, 0x37, 0xdd, 0x0d, 0x9f, 0x59, 0xd1, 0x97, 0x9b, 0x95, + 0x5d, 0xba, 0x4d, 0x37, 0x69, 0xe8, 0xe0, 0x51, 0xa0, 0xa9, 0xe4, 0x87, + 0x95, 0xae, 0x37, 0x0f, 0x21, 0x10, 0x8c, 0x27, 0x89, 0x84, 0x51, 0x1c, + 0x2c, 0xe2, 0xe5, 0x54, 0xb4, 0x75, 0xfb, 0x3d, 0x49, 0xf4, 0x7c, 0x15, + 0xe2, 0x0b, 0xdc, 0x0e, 0xbd, 0xd4, 0x13, 0x5b, 0x38, 0x41, 0x62, 0x23, + 0xab, 0x9a, 0xa5, 0xb8, 0xf8, 0x4d, 0x9e, 0x66, 0x2e, 0xc7, 0xae, 0x9e, + 0x8b, 0x73, 0xb8, 0xc7, 0x78, 0x5f, 0xc6, 0x54, 0xea, 0xb2, 0xf5, 0x5e, + 0xef, 0xda, 0xd5, 0x31, 0x4a, 0xb2, 0x0d, 0xd5, 0xf8, 0xa1, 0xb5, 0x67, + 0x4d, 0xaf, 0xb5, 0x04, 0x07, 0xf4, 0x3c, 0xce, 0x0d, 0x7d, 0x46, 0x4f, + 0xb3, 0xf3, 0x08, 0x09, 0x47, 0x3e, 0xe7, 0xec, 0xb9, 0x90, 0x54, 0x02, + 0xfb, 0xad, 0x50, 0xb9, 0x9e, 0x46, 0x40, 0x9a, 0x0e, 0xcb, 0x08, 0x65, + 0x78, 0x23, 0x2c, 0xba, 0xbf, 0x2a, 0xae, 0x23, 0xf2, 0xa7, 0xa6, 0x68, + 0xe7, 0x7c, 0xee, 0x35, 0xc2, 0xa6, 0x01, 0xa4, 0x36, 0x26, 0xb6, 0xb7, + 0x37, 0x85, 0xe8, 0xe8, 0xee, 0x2f, 0xe0, 0xa5, 0x94, 0xa3, 0x81, 0x54, + 0xc8, 0xf8, 0xde, 0xee, 0xf1, 0x4a, 0x08, 0x7d, 0x78, 0xf6, 0x8a, 0xf4, + 0x6f, 0x2e, 0x5e, 0xf8, 0x50, 0xa5, 0xdf, 0x28, 0x31, 0x9d, 0x44, 0x52, + 0x10, 0x69, 0x41, 0x35, 0xd3, 0x10, 0xa5, 0x7f, 0x09, 0x21, 0x28, 0x68, + 0x25, 0xf9, 0xbb, 0x9e, 0x92, 0x84, 0xb5, 0x50, 0xa6, 0xd4, 0x92, 0x0a, + 0x84, 0xe4, 0x17, 0x84, 0x23, 0x3b, 0xc1, 0x91, 0x5d, 0xe0, 0xac, 0x75, + 0xc9, 0xca, 0x6a, 0x5c, 0x7a, 0xd0, 0x75, 0x23, 0xec, 0x1b, 0x3f, 0x94, + 0xec, 0xe8, 0xe6, 0xa9, 0xb0, 0xf9, 0x01, 0x2c, 0x20, 0xb0, 0x0d, 0x5a, + 0x6e, 0xe9, 0x95, 0x87, 0x91, 0xc2, 0xa5, 0x77, 0xfb, 0x43, 0x9a, 0x41, + 0x9c, 0xa8, 0x9b, 0xf9, 0x40, 0x81, 0xc6, 0xc1, 0xa3, 0x2e, 0x66, 0xd2, + 0x04, 0x27, 0x28, 0x3b, 0x05, 0xbe, 0x98, 0x73, 0x74, 0x44, 0x9d, 0x49, + 0x49, 0xe6, 0xab, 0x58, 0xdd, 0x18, 0xc7, 0x1d, 0x4a, 0x22, 0xb6, 0x93, + 0x74, 0x76, 0xed, 0xe2, 0x2f, 0x64, 0x34, 0x12, 0x23, 0x64, 0x14, 0x37, + 0x14, 0xef, 0xe0, 0xf7, 0xe1, 0xb2, 0xfb, 0x26, 0xe2, 0x3e, 0xa4, 0xb8, + 0x3c, 0x5c, 0xf3, 0x99, 0xc0, 0x2f, 0x0d, 0x8f, 0x26, 0x8c, 0xcf, 0x85, + 0x36, 0xc4, 0x7e, 0x4c, 0x0c, 0x4d, 0x44, 0x6c, 0x39, 0x55, 0x8d, 0x17, + 0x24, 0xd1, 0x24, 0x96, 0xb2, 0x63, 0xf4, 0x36, 0x3f, 0x9d, 0xf2, 0x59, + 0xce, 0x0d, 0x9d, 0x2a, 0xe9, 0x84, 0xbd, 0x25, 0x34, 0xe5, 0x24, 0x10, + 0x80, 0xa9, 0xda, 0xeb, 0xb3, 0x7f, 0x01, 0xf7, 0x98, 0x98, 0x8c, 0xfe, + 0x6c, 0x43, 0xba, 0x01, 0xce, 0xdc, 0xd3, 0xf6, 0x93, 0xfa, 0xbc, 0x5b, + 0x52, 0xb7, 0xfe, 0x83, 0xe7, 0x02, 0xd8, 0xcd, 0xc9, 0xeb, 0xc8, 0xdc, + 0xef, 0x3f, 0xd0, 0xe7, 0x3d, 0x18, 0x3b, 0x1e, 0xfc, 0xc3, 0x5f, 0x42, + 0xed, 0x7a, 0x58, 0xe9, 0x7a, 0x44, 0xb2, 0xd4, 0x48, 0x5e, 0x76, 0x11, + 0x8e, 0xd4, 0xfc, 0xb5, 0xfc, 0x67, 0xdc, 0xd8, 0x87, 0xc1, 0x9a, 0x47, + 0x3a, 0x56, 0x47, 0xbe, 0xb3, 0x99, 0xc3, 0xa2, 0xc2, 0xff, 0x72, 0x7e, + 0xbf, 0xa7, 0xae, 0xb6, 0x24, 0xd5, 0xff, 0x54, 0x5f, 0xe2, 0xae, 0xff, + 0x90, 0x98, 0x98, 0xa2, 0x44, 0xc1, 0x3c, 0xef, 0x71, 0x30, 0x2b, 0xf9, + 0x0c, 0x8d, 0x1f, 0xf8, 0x43, 0x80, 0x68, 0xf4, 0x0b, 0xd1, 0x7f, 0x94, + 0x29, 0xe1, 0x53, 0x98, 0xd8, 0x3f, 0xfe, 0x45, 0xda, 0xb5, 0xc5, 0xe5, + 0x99, 0x66, 0xce, 0x3b, 0x9c, 0xf9, 0x23, 0xaf, 0x18, 0x54, 0xb7, 0xf3, + 0xe6, 0x23, 0x22, 0x91, 0x5b, 0xc9, 0xc9, 0x75, 0x1e, 0xf2, 0x13, 0xb1, + 0x42, 0x36, 0x41, 0x4c, 0xe6, 0xbd, 0x79, 0xc7, 0x5e, 0xf7, 0x3c, 0x01, + 0x0a, 0x81, 0x99, 0xab, 0xe1, 0x65, 0xda, 0x86, 0xa6, 0xc1, 0x66, 0x24, + 0xaf, 0xb3, 0x9b, 0xab, 0xb0, 0x40, 0xed, 0x54, 0x5d, 0x82, 0x40, 0x3b, + 0xf3, 0xf3, 0xa8, 0x38, 0x3b, 0xde, 0x76, 0xb5, 0x2b, 0x62, 0x15, 0xb9, + 0x7e, 0x36, 0x0b, 0x9f, 0xa9, 0xbd, 0xe1, 0x15, 0x3a, 0x14, 0x71, 0x8e, + 0x1b, 0x30, 0x4b, 0xfb, 0x6e, 0x0f, 0x10, 0x87, 0x19, 0xd8, 0xc7, 0xcf, + 0xa1, 0xae, 0xe0, 0x6e, 0xef, 0x98, 0x09, 0x17, 0x0a, 0x66, 0x75, 0x93, + 0x03, 0x81, 0xa0, 0xe0, 0x47, 0x13, 0x0e, 0x23, 0xef, 0xa4, 0x37, 0x9a, + 0x3b, 0xda, 0xac, 0xde, 0xeb, 0x8f, 0x32, 0x35, 0x9f, 0x77, 0xe6, 0x52, + 0xbd, 0x58, 0xdb, 0x55, 0x93, 0x82, 0x79, 0x5b, 0x3d, 0x8e, 0xd7, 0xb0, + 0x5a, 0xb3, 0x34, 0xa4, 0x20, 0x89, 0x7f, 0x11, 0x8b, 0xcc, 0xd8, 0xf7, + 0x58, 0x8b, 0xbf, 0x8f, 0x5b, 0xd5, 0xe7, 0x7f, 0xe0, 0x23, 0x60, 0x18, + 0xbb, 0x1c, 0x94, 0x0a, 0x22, 0xaa, 0x9a, 0xdd, 0x53, 0x1e, 0xfa, 0xd9, + 0xc5, 0xf3, 0xb9, 0x00, 0x0c, 0xc4, 0xd7, 0xa6, 0xea, 0x94, 0xe7, 0x58, + 0xd9, 0xbd, 0x52, 0x95, 0xfc, 0x24, 0x69, 0xf8, 0x9b, 0x29, 0xa6, 0xa5, + 0x91, 0x04, 0x50, 0x92, 0xa6, 0x41, 0x24, 0x62, 0x10, 0x0d, 0x05, 0x97, + 0x76, 0xf3, 0x2c, 0xb7, 0xe4, 0x2e, 0xe8, 0x44, 0xd1, 0x1b, 0x24, 0x07, + 0x5e, 0x8a, 0xa0, 0xdf, 0x93, 0x4d, 0x09, 0x2f, 0x76, 0xf4, 0xbb, 0x28, + 0x4a, 0x89, 0xd0, 0x01, 0x87, 0x8e, 0xb6, 0x69, 0xa7, 0xae, 0x37, 0xf3, + 0x17, 0x9d, 0xfe, 0xb8, 0x2d, 0xc5, 0x68, 0xed, 0xa3, 0x59, 0x7d, 0xe2, + 0x3c, 0x92, 0xd1, 0xb4, 0x8a, 0x44, 0xfb, 0x17, 0x87, 0xfb, 0xb4, 0xea, + 0xd6, 0x7b, 0xe2, 0xbe, 0xe8, 0xd2, 0x7d, 0x6c, 0x4c, 0x00, 0x16, 0x76, + 0x77, 0x79, 0x0a, 0x32, 0xd3, 0xe6, 0xf2, 0xb4, 0x82, 0xef, 0xd4, 0x92, + 0x6a, 0xca, 0xc5, 0xe9, 0xa8, 0xcf, 0x19, 0xf0, 0xe3, 0xc1, 0x3c, 0x93, + 0x2d, 0x6d, 0xa2, 0x38, 0x2e, 0xcc, 0x22, 0x5e, 0xbd, 0x53, 0xba, 0xba, + 0xd8, 0x17, 0x62, 0x74, 0x53, 0x2d, 0x8b, 0x53, 0xd8, 0x98, 0x57, 0xab, + 0x1d, 0xa9, 0x09, 0x47, 0x47, 0x8b, 0x09, 0x59, 0xd0, 0xe2, 0xb4, 0x21, + 0x51, 0x6c, 0x8f, 0xde, 0x6e, 0x60, 0xf3, 0x35, 0x82, 0xea, 0xbb, 0xfe, + 0x8b, 0x70, 0xe4, 0xc3, 0x5a, 0x90, 0x3a, 0x16, 0xfb, 0x19, 0x70, 0xc2, + 0xf0, 0x08, 0xbb, 0xd6, 0x47, 0x79, 0x65, 0x02, 0x90, 0x5e, 0xa2, 0x69, + 0x91, 0x28, 0x9e, 0x09, 0x60, 0xc1, 0x75, 0x7f, 0x9c, 0x2c, 0x0e, 0xf9, + 0xda, 0xa8, 0x49, 0x86, 0xf1, 0x1b, 0xfd, 0x9e, 0x51, 0x84, 0xce, 0x66, + 0xde, 0x10, 0x1a, 0x0c, 0xce, 0x7c, 0x89, 0x9b, 0x0e, 0x16, 0x26, 0x08, + 0xd9, 0x69, 0xa1, 0xa5, 0x21, 0x6c, 0xf9, 0xe9, 0x3d, 0xbc, 0x1e, 0x58, + 0xe2, 0x5e, 0x37, 0x2a, 0xe9, 0xb9, 0x80, 0x78, 0xf9, 0x7a, 0x99, 0x08, + 0xc4, 0x9b, 0x5a, 0xea, 0x75, 0x9c, 0xfe, 0x9a, 0x18, 0x7e, 0x66, 0x09, + 0xf7, 0x5b, 0x6e, 0xf5, 0x43, 0xbd, 0x29, 0x55, 0x39, 0x1e, 0x21, 0xfb, + 0x09, 0x2b, 0xdb, 0x69, 0xf9, 0x34, 0x66, 0xf2, 0xdd, 0xbb, 0x77, 0xc4, + 0xb4, 0xb4, 0x11, 0x3f, 0x7f, 0xaa, 0xe7, 0xe5, 0xe5, 0xb5, 0x8f, 0x5b, + 0xcc, 0x8d, 0x33, 0x7c, 0xf4, 0xf7, 0x3a, 0x1e, 0xf8, 0xc0, 0x67, 0xd5, + 0x59, 0x03, 0xc6, 0xec, 0xd0, 0x66, 0x84, 0xba, 0xe8, 0x15, 0x3f, 0x0e, + 0x8d, 0xc9, 0xec, 0x3d, 0xf8, 0xf4, 0x59, 0x24, 0x09, 0xf9, 0x11, 0xe8, + 0xbe, 0x86, 0xc4, 0x32, 0xf8, 0x12, 0x09, 0x6c, 0x3d, 0x78, 0x37, 0xeb, + 0xd4, 0x73, 0x77, 0xe0, 0xed, 0x96, 0xe1, 0x4d, 0x5e, 0xd3, 0x22, 0x72, + 0xbe, 0x54, 0x40, 0x16, 0xe7, 0xb2, 0xa6, 0x63, 0x5a, 0x17, 0x2d, 0x55, + 0xef, 0xe2, 0xe1, 0xda, 0xc5, 0x65, 0x07, 0x1d, 0xb2, 0xf7, 0x5e, 0x4e, + 0xab, 0xa4, 0x54, 0xfc, 0x15, 0x8c, 0x52, 0xf3, 0x74, 0x51, 0xba, 0xb4, + 0xb5, 0xc2, 0xd3, 0x5c, 0x46, 0xb5, 0x04, 0xf0, 0xad, 0x91, 0x60, 0x8e, + 0xda, 0xc5, 0xd9, 0xd2, 0xac, 0x2c, 0x10, 0xea, 0xf7, 0xe3, 0xa1, 0x8c, + 0xfe, 0x38, 0xd5, 0xb3, 0x35, 0xba, 0x73, 0xd2, 0xfc, 0x74, 0x9e, 0x0b, + 0x62, 0x84, 0x01, 0x48, 0x31, 0xb4, 0x8f, 0xf7, 0x6f, 0x7e, 0x43, 0x46, + 0x69, 0x75, 0xf4, 0xa6, 0x01, 0x31, 0x81, 0x55, 0x30, 0x92, 0xd1, 0xc5, + 0x83, 0x5b, 0x18, 0xf6, 0x59, 0x4d, 0xf1, 0xd5, 0xfe, 0x86, 0x04, 0xb9, + 0x8d, 0xb9, 0x7a, 0x32, 0xd6, 0x77, 0x61, 0x17, 0xee, 0xbb, 0x3f, 0x5b, + 0x97, 0x5f, 0x4b, 0xe6, 0xe6, 0xee, 0x82, 0x19, 0xf0, 0x53, 0x62, 0xb9, + 0x43, 0x80, 0x04, 0x53, 0x66, 0x4f, 0x98, 0xd0, 0x5a, 0x56, 0x93, 0x4b, + 0xaf, 0x38, 0xeb, 0x2c, 0xa3, 0xcf, 0x14, 0xb8, 0x38, 0x7a, 0xa4, 0xaa, + 0x6a, 0x98, 0xff, 0xb4, 0xd2, 0x70, 0x86, 0x92, 0xc5, 0xa5, 0xa6, 0x7e, + 0xee, 0xef, 0x57, 0x33, 0xbb, 0x62, 0x85, 0x40, 0xd0, 0xea, 0x96, 0xfd, + 0xc5, 0x07, 0x07, 0x0d, 0xa5, 0xb9, 0x2e, 0x84, 0x77, 0x8f, 0x3b, 0x49, + 0xab, 0x9d, 0xa7, 0xff, 0x94, 0x09, 0x73, 0xb7, 0x36, 0xd6, 0x32, 0xcc, + 0x5f, 0xd2, 0xc9, 0xca, 0x0d, 0x52, 0xef, 0x89, 0x23, 0xdd, 0x06, 0xfc, + 0xf0, 0x46, 0x60, 0x74, 0x9a, 0x6f, 0xd0, 0x25, 0xa0, 0xf1, 0xb7, 0xa3, + 0x22, 0x74, 0xbb, 0x53, 0x68, 0x68, 0xf2, 0x31, 0xba, 0xba, 0xfb, 0x39, + 0x49, 0x22, 0x10, 0x47, 0xb7, 0x52, 0x27, 0x6c, 0x39, 0x32, 0x0a, 0x32, + 0x37, 0xb8, 0x8e, 0xae, 0xee, 0x9a, 0xdc, 0xc8, 0x30, 0x11, 0x1a, 0x45, + 0x1d, 0xbc, 0x5b, 0xea, 0xdf, 0x9f, 0x04, 0xfd, 0x4a, 0x8b, 0x1e, 0xab, + 0x4c, 0x71, 0x76, 0x76, 0xec, 0x4c, 0xff, 0xeb, 0xa7, 0x1e, 0x7b, 0x33, + 0x1f, 0xbb, 0xbb, 0xbb, 0xf5, 0xce, 0x3d, 0x97, 0xef, 0xc5, 0x39, 0x91, + 0x70, 0x9e, 0x49, 0x8d, 0xc3, 0xfd, 0x96, 0x38, 0x4e, 0x78, 0x5e, 0xc6, + 0x40, 0xc7, 0x68, 0x25, 0xee, 0x95, 0xd0, 0x35, 0x53, 0x11, 0x4f, 0x31, + 0x39, 0x21, 0x88, 0x86, 0x14, 0x96, 0xf6, 0xfa, 0x63, 0x20, 0x39, 0x32, + 0x53, 0x7c, 0x23, 0x8e, 0x09, 0xf7, 0x58, 0x16, 0xf5, 0xfc, 0x2d, 0xb4, + 0xbd, 0x1d, 0xfb, 0x8e, 0x96, 0x26, 0x5a, 0xbd, 0xce, 0x10, 0x9e, 0x84, + 0x5e, 0xbb, 0xf9, 0x4d, 0x04, 0x46, 0x80, 0xba, 0x81, 0x9a, 0xd7, 0x5c, + 0xa6, 0x69, 0x74, 0x58, 0xb4, 0x4f, 0x78, 0xd9, 0xf7, 0x93, 0x4d, 0x86, + 0x37, 0x56, 0x7e, 0x7e, 0xd9, 0x61, 0xe2, 0x4d, 0xc8, 0x65, 0x37, 0x32, + 0xd4, 0xda, 0x7c, 0x6e, 0x78, 0xda, 0x5b, 0xf7, 0x5d, 0x0b, 0x20, 0x1e, + 0xae, 0x12, 0x76, 0x44, 0x5c, 0x6f, 0x05, 0x08, 0xe9, 0x24, 0x3f, 0xdf, + 0xe6, 0xa8, 0x1d, 0x26, 0xf7, 0xa6, 0x40, 0xa2, 0xe0, 0xf3, 0x2a, 0x32, + 0x08, 0x96, 0x7f, 0x8c, 0x98, 0x41, 0x6f, 0xe6, 0xf7, 0x0b, 0x13, 0x19, + 0x08, 0x92, 0xc1, 0x99, 0x7f, 0x24, 0x97, 0x71, 0x10, 0x6e, 0x2a, 0x1d, + 0x13, 0x81, 0x27, 0xf4, 0xaf, 0x8c, 0x84, 0x97, 0xbc, 0x98, 0x2d, 0x60, + 0x30, 0xf1, 0x3f, 0x3f, 0x05, 0x05, 0x05, 0xbd, 0xb6, 0xd2, 0x3d, 0x8f, + 0x0e, 0x9a, 0x0e, 0x6b, 0x77, 0x45, 0x2e, 0xbb, 0xef, 0x3c, 0x57, 0x0a, + 0x43, 0x0f, 0x74, 0x38, 0x0b, 0xa7, 0x85, 0x53, 0xe2, 0xcc, 0x8c, 0x43, + 0xcc, 0x48, 0x34, 0x20, 0x42, 0x07, 0x2c, 0x1a, 0xdf, 0xac, 0xba, 0x1c, + 0x2a, 0x4d, 0x7f, 0x8b, 0x52, 0x4d, 0x6c, 0x28, 0x6b, 0x1d, 0x3d, 0xa9, + 0x11, 0x73, 0x85, 0xf9, 0xdd, 0x65, 0xd7, 0x26, 0xcb, 0x30, 0x23, 0x8c, + 0xc9, 0x00, 0x80, 0x94, 0x05, 0x32, 0x21, 0xa4, 0x9f, 0x0e, 0x05, 0x0f, + 0x8f, 0x4e, 0xb7, 0x5d, 0xef, 0x3e, 0x5f, 0xf8, 0x70, 0xd8, 0x42, 0xef, + 0x13, 0xe5, 0x77, 0x73, 0xb1, 0x5a, 0xd9, 0xc7, 0x20, 0xaf, 0xa7, 0x97, + 0xa4, 0xf6, 0x8f, 0xb9, 0xda, 0xb1, 0x8b, 0xf4, 0x52, 0xe3, 0xd3, 0x78, + 0xd6, 0xdf, 0xb1, 0xbf, 0xa2, 0xeb, 0x51, 0x7e, 0x18, 0x45, 0xef, 0xfe, + 0x02, 0x10, 0x66, 0xb1, 0x58, 0xd7, 0x8e, 0x35, 0xd2, 0x0c, 0x7a, 0x21, + 0x8a, 0x59, 0x61, 0xf2, 0x4b, 0xfd, 0x7d, 0x59, 0x01, 0x86, 0x00, 0xc0, + 0x54, 0xc2, 0x85, 0x3a, 0xb2, 0xd2, 0xf8, 0x72, 0x47, 0x8e, 0xd5, 0xff, + 0xa8, 0x4a, 0xed, 0x15, 0x95, 0xb1, 0xb3, 0x11, 0x1a, 0xca, 0xe2, 0xd4, + 0x51, 0xc2, 0xaa, 0xee, 0xee, 0x7d, 0x1a, 0x68, 0x9b, 0x1f, 0x41, 0x47, + 0xf3, 0xcb, 0xf7, 0x14, 0xb8, 0xb8, 0xb8, 0x0c, 0x76, 0x82, 0xc9, 0x5f, + 0xbe, 0xac, 0x34, 0xfe, 0x2d, 0x93, 0x77, 0x74, 0x2c, 0x53, 0xfb, 0x37, + 0x13, 0x37, 0x6d, 0xbe, 0x11, 0xdf, 0x40, 0xd9, 0xc2, 0xb6, 0x45, 0xe7, + 0x1d, 0x6c, 0x05, 0x34, 0x3a, 0x58, 0xb9, 0x4b, 0xee, 0x64, 0xa6, 0xfe, + 0x2a, 0x98, 0x27, 0xb4, 0xa1, 0x91, 0xe7, 0x78, 0xfb, 0x2e, 0xfe, 0x53, + 0x55, 0x5f, 0x5e, 0x70, 0x70, 0x16, 0x06, 0x4e, 0x59, 0x2b, 0xd9, 0x79, + 0x93, 0x5b, 0x8e, 0x7c, 0x4d, 0xf8, 0x30, 0xaf, 0x23, 0x18, 0x49, 0x5d, + 0x0b, 0x77, 0x1c, 0xb9, 0xad, 0x51, 0x47, 0x30, 0x6d, 0xbf, 0x98, 0xdc, + 0x95, 0x52, 0xb1, 0x86, 0x3f, 0x19, 0xce, 0xd6, 0x08, 0x0b, 0x55, 0x56, + 0xc5, 0x96, 0x51, 0x7e, 0x33, 0x35, 0x16, 0x7b, 0xaf, 0xa9, 0xcd, 0x8f, + 0x1d, 0xa8, 0xc4, 0xe0, 0xdd, 0x0d, 0x8b, 0x69, 0x97, 0x97, 0x97, 0x3f, + 0xde, 0xab, 0x1e, 0xb5, 0xb8, 0xbf, 0xfd, 0xc7, 0xbd, 0x71, 0xcc, 0x3e, + 0x11, 0x97, 0x60, 0x86, 0x0e, 0x25, 0x8b, 0x35, 0xd3, 0xf9, 0x2d, 0xd1, + 0xd6, 0xb0, 0x78, 0xd0, 0xbe, 0xda, 0xad, 0x3d, 0xe3, 0xce, 0x8b, 0x46, + 0xf1, 0xf7, 0x9f, 0x62, 0xc5, 0xac, 0x43, 0xb0, 0xfc, 0xc1, 0x36, 0xfb, + 0x7c, 0x8e, 0x09, 0xd8, 0x4d, 0xc9, 0xca, 0xe0, 0x5e, 0x83, 0xec, 0xbc, + 0x07, 0x0d, 0x6d, 0xfa, 0xe0, 0xfb, 0xf7, 0x99, 0x59, 0x7b, 0x99, 0x06, + 0xce, 0xe9, 0x2e, 0x87, 0xd6, 0x66, 0x97, 0x4d, 0x04, 0x58, 0x4e, 0x99, + 0x3d, 0x8c, 0x84, 0xea, 0x45, 0x1e, 0xda, 0x0a, 0xa8, 0xbe, 0xad, 0x4d, + 0x9a, 0x87, 0x9b, 0x7b, 0x33, 0x43, 0xc7, 0xc4, 0x64, 0xd8, 0x5d, 0x8c, + 0xde, 0xa9, 0xd1, 0x7a, 0x82, 0x08, 0x66, 0xab, 0xbb, 0xd9, 0xc0, 0x38, + 0x80, 0x65, 0x1b, 0x13, 0x61, 0x31, 0x26, 0xc6, 0xe4, 0xfc, 0x4d, 0x43, + 0x98, 0xbb, 0xfb, 0xf4, 0x32, 0x0d, 0x2c, 0x87, 0x73, 0x0c, 0x8e, 0xda, + 0xdc, 0xad, 0x74, 0x56, 0x75, 0x8b, 0xa0, 0xe0, 0x3a, 0xb1, 0xe5, 0x77, + 0xe2, 0xf7, 0xbd, 0x3a, 0xd2, 0x50, 0x5f, 0x1a, 0x56, 0x59, 0x60, 0xc1, + 0xf1, 0xe7, 0x8b, 0xc4, 0x94, 0x7c, 0x82, 0xf3, 0x09, 0x5d, 0x6c, 0xf5, + 0x82, 0x44, 0x6e, 0xee, 0x23, 0x43, 0x03, 0xe9, 0x2f, 0x42, 0x21, 0xa3, + 0x9d, 0x92, 0x6f, 0xcb, 0x1f, 0xce, 0xb6, 0x3f, 0x6e, 0x65, 0x7c, 0x18, + 0x59, 0x9f, 0x96, 0xf8, 0x70, 0xc1, 0xa9, 0xa5, 0xad, 0xbd, 0x38, 0xf9, + 0x1d, 0x0e, 0xfa, 0x82, 0x1e, 0x86, 0x6e, 0xc9, 0x6c, 0xee, 0xe9, 0xa3, + 0x52, 0x56, 0x0b, 0x9a, 0xc1, 0xce, 0x4a, 0xe3, 0x73, 0x47, 0xdb, 0x12, + 0xc2, 0x87, 0x59, 0x48, 0x07, 0x12, 0x6d, 0x2d, 0x50, 0x60, 0x85, 0x11, + 0xf6, 0x22, 0x2c, 0x03, 0x37, 0xd0, 0x8a, 0x2c, 0x47, 0xde, 0xd7, 0x80, + 0x98, 0x70, 0x7a, 0xe5, 0x64, 0x71, 0xfa, 0x6b, 0xe7, 0x5f, 0x7d, 0x8b, + 0x8d, 0xa5, 0x3d, 0x1d, 0x1a, 0x6c, 0x75, 0x04, 0x81, 0x46, 0xec, 0x04, + 0xa8, 0x21, 0x08, 0x70, 0x66, 0x8e, 0x8a, 0x0c, 0x0c, 0xdf, 0x63, 0x63, + 0x30, 0x91, 0xc1, 0x29, 0x75, 0xa8, 0xea, 0xa7, 0xcd, 0x68, 0xc6, 0xfe, + 0xb7, 0xf3, 0x92, 0x1b, 0xcc, 0xed, 0x69, 0x64, 0x3b, 0x06, 0xfa, 0x37, + 0xda, 0x8f, 0x15, 0x71, 0x41, 0x63, 0x7f, 0x85, 0xa0, 0x91, 0x34, 0xf3, + 0xd5, 0x5b, 0x99, 0xb7, 0x5f, 0x1a, 0xa4, 0x81, 0x30, 0x84, 0x25, 0x4f, + 0xfc, 0x55, 0x52, 0x07, 0xa5, 0xd0, 0x83, 0x50, 0xb7, 0x67, 0xd6, 0x19, + 0x96, 0x32, 0xbc, 0xde, 0xfe, 0xfb, 0xbb, 0x14, 0xe8, 0x64, 0x5e, 0x56, + 0x77, 0xf0, 0xfa, 0xa7, 0xe4, 0x08, 0x7f, 0x02, 0x96, 0xbc, 0x13, 0x8e, + 0x8e, 0xce, 0xf6, 0x39, 0x72, 0x67, 0x7d, 0x2c, 0x45, 0xa7, 0xce, 0x71, + 0x71, 0xf7, 0xd8, 0xd2, 0x54, 0x53, 0xb3, 0x1d, 0x03, 0x03, 0xc3, 0x88, + 0xd5, 0x4d, 0x16, 0xc7, 0xcf, 0x68, 0xe0, 0x83, 0x2c, 0x0e, 0x04, 0xe1, + 0x66, 0x10, 0x4f, 0xf6, 0x8f, 0x84, 0x86, 0x74, 0x77, 0xa6, 0x12, 0xd6, + 0xc0, 0x39, 0xc4, 0xf0, 0x6a, 0xb3, 0x8a, 0xf3, 0xb4, 0xed, 0x76, 0x83, + 0xc7, 0x31, 0xde, 0x5b, 0xd3, 0x57, 0xa6, 0xdd, 0xb2, 0x0e, 0x3e, 0x40, + 0x2a, 0x87, 0x03, 0xc9, 0x7b, 0x1c, 0x79, 0x4e, 0x84, 0xad, 0xe3, 0x0e, + 0xaa, 0x67, 0xc2, 0x91, 0x10, 0x12, 0xfa, 0xbd, 0x3e, 0x70, 0x3b, 0x2c, + 0xbc, 0xec, 0x90, 0xf8, 0xf3, 0x25, 0x1f, 0x6f, 0x66, 0x65, 0x71, 0x27, + 0x59, 0x0b, 0x35, 0x2a, 0x41, 0x6f, 0x26, 0xcb, 0xcd, 0xf2, 0xdb, 0xf5, + 0x57, 0x3c, 0x6d, 0xd5, 0x8b, 0x88, 0x24, 0xcf, 0x62, 0x95, 0x12, 0x44, + 0xb7, 0x90, 0x6d, 0x27, 0x83, 0xcf, 0x1d, 0x97, 0xbe, 0x16, 0x0f, 0xd6, + 0xcc, 0xbd, 0x7d, 0xf3, 0xdc, 0x9b, 0x07, 0x98, 0x36, 0x96, 0x5b, 0xad, + 0x78, 0xff, 0x01, 0x87, 0x26, 0xc1, 0x5e, 0x46, 0x06, 0x34, 0x3a, 0x3c, + 0x7c, 0x6e, 0xcb, 0x6f, 0x56, 0x63, 0x9f, 0xf8, 0xd5, 0x92, 0x5b, 0x9f, + 0xa5, 0xf0, 0x41, 0x80, 0xf5, 0x10, 0x03, 0x88, 0xce, 0x2f, 0x2b, 0xbb, + 0x9a, 0xe9, 0x5d, 0xaa, 0x09, 0xf2, 0x2c, 0xbe, 0x4a, 0xc7, 0x99, 0x8a, + 0x8e, 0xdc, 0x81, 0xe6, 0xbc, 0x3c, 0xc4, 0xcd, 0xbf, 0x7f, 0xa2, 0x2d, + 0x3c, 0xc2, 0x3a, 0x20, 0xb4, 0x00, 0x2c, 0x39, 0xc5, 0x67, 0x3e, 0xcc, + 0x28, 0x73, 0x65, 0xea, 0x64, 0xb9, 0xf7, 0xe1, 0xbd, 0x7f, 0x7c, 0x96, + 0xfd, 0x2e, 0xbd, 0x05, 0x52, 0x8d, 0x4a, 0xf5, 0xa4, 0x60, 0xbd, 0x04, + 0x5b, 0x06, 0x73, 0x83, 0x18, 0xe8, 0x8e, 0x0c, 0xb9, 0x7b, 0xf4, 0x4c, + 0x80, 0x77, 0x8d, 0x22, 0x35, 0xd7, 0x21, 0xad, 0xaf, 0x4a, 0xe1, 0x50, + 0x32, 0x6f, 0x6b, 0xeb, 0x6f, 0x4a, 0xa4, 0xd7, 0x7f, 0xcb, 0xdb, 0x0e, + 0xf8, 0x47, 0x8c, 0xcb, 0x19, 0xfd, 0x9a, 0x3a, 0xeb, 0x02, 0x51, 0x41, + 0x9b, 0x53, 0x8c, 0x56, 0x0f, 0x61, 0x7a, 0xb4, 0xa7, 0x08, 0x0b, 0x4a, + 0x97, 0xf0, 0xae, 0x52, 0x4a, 0x00, 0x46, 0xb2, 0x4d, 0xdb, 0xd7, 0x68, + 0x44, 0x94, 0x9d, 0xa5, 0x2c, 0x7b, 0x20, 0x00, 0x33, 0x38, 0x0d, 0x1c, + 0xb2, 0xf5, 0xd7, 0x58, 0x32, 0xb6, 0x1a, 0x15, 0x46, 0xb5, 0x0e, 0xc7, + 0xb6, 0x72, 0x01, 0xeb, 0x51, 0xc2, 0xc8, 0xf8, 0x06, 0xb3, 0xde, 0x30, + 0x62, 0xa7, 0x9d, 0x2f, 0x2d, 0x18, 0xa8, 0x40, 0x50, 0x0a, 0x5b, 0x74, + 0xab, 0xc8, 0x92, 0x61, 0xc4, 0xe4, 0xf2, 0x75, 0x28, 0x2a, 0x28, 0x38, + 0x7f, 0x1d, 0xde, 0x1c, 0x47, 0x48, 0xb9, 0xac, 0x29, 0x14, 0x20, 0x1c, + 0x7d, 0xe5, 0x67, 0xc5, 0x65, 0x00, 0xaf, 0xaf, 0x40, 0x2a, 0x34, 0xce, + 0xf4, 0xc8, 0x90, 0x48, 0x2e, 0xd3, 0xe6, 0x99, 0xdc, 0x81, 0x05, 0x8b, + 0xca, 0x7a, 0xf5, 0xc3, 0xa2, 0x71, 0x82, 0xb4, 0xbc, 0xed, 0xc7, 0x28, + 0x7f, 0x7d, 0xd1, 0x60, 0x68, 0x6a, 0xe3, 0x29, 0xc6, 0x1f, 0x2e, 0x0f, + 0x86, 0xff, 0xee, 0xee, 0x4a, 0xa4, 0x8d, 0x25, 0xf3, 0x98, 0x1d, 0x4c, + 0x52, 0x6b, 0xc0, 0xd9, 0x78, 0x9d, 0xf9, 0xb5, 0x2f, 0x08, 0x01, 0x5f, + 0x20, 0x26, 0x48, 0xc5, 0xd3, 0xaf, 0x4b, 0x91, 0x76, 0xea, 0xb6, 0xea, + 0x15, 0xa7, 0x5b, 0xa3, 0x9e, 0x2a, 0xad, 0x40, 0x02, 0x0b, 0x32, 0x7c, + 0xc2, 0x63, 0x68, 0x85, 0xa3, 0x9d, 0xe6, 0x7e, 0xec, 0x84, 0x27, 0x78, + 0x6b, 0x68, 0x10, 0x5e, 0x5e, 0x5e, 0x7a, 0xfa, 0x07, 0xb4, 0x2a, 0xfc, + 0xff, 0x99, 0xa1, 0x04, 0xa9, 0xf8, 0x05, 0x7d, 0xfb, 0x4d, 0x1e, 0xfb, + 0xae, 0x2a, 0xed, 0xa1, 0x84, 0xf4, 0xf6, 0x65, 0x13, 0x7f, 0xcf, 0x9b, + 0xb3, 0xb2, 0xb2, 0x16, 0x07, 0x8c, 0x93, 0xac, 0xfc, 0x2f, 0x17, 0x3d, + 0xc5, 0x89, 0x74, 0xab, 0x1f, 0x61, 0x69, 0x50, 0xe7, 0xac, 0xf4, 0xb1, + 0xa3, 0x9c, 0xc1, 0x80, 0x85, 0x38, 0x8d, 0x4b, 0xa8, 0x7d, 0x1d, 0xb3, + 0x6f, 0x39, 0x0d, 0xc6, 0xa7, 0x6c, 0x54, 0x1f, 0x68, 0xf4, 0xfd, 0x77, + 0xe2, 0xc1, 0x7e, 0x36, 0x51, 0xf0, 0x1a, 0xde, 0x9b, 0x02, 0xb7, 0xa9, + 0x1f, 0x25, 0xbf, 0xdd, 0x06, 0x32, 0xab, 0xae, 0x29, 0x06, 0x92, 0x6b, + 0x7e, 0xbc, 0xf5, 0x3b, 0xeb, 0xdb, 0xb2, 0x95, 0x81, 0xa2, 0x8b, 0x4b, + 0xa5, 0xda, 0x5d, 0xc5, 0xdb, 0x2e, 0xe3, 0xda, 0xcb, 0xfd, 0xf9, 0xe9, + 0x83, 0x77, 0xa5, 0x06, 0xd5, 0x58, 0xc8, 0xd3, 0x5e, 0x2e, 0xac, 0xc4, + 0xa2, 0xcb, 0xe4, 0x7d, 0x29, 0x54, 0x19, 0xc8, 0x21, 0x77, 0x96, 0x03, + 0xb5, 0xf1, 0x5b, 0x5a, 0x5b, 0x97, 0xf2, 0x75, 0x4d, 0x74, 0x74, 0xba, + 0x05, 0x69, 0x5e, 0xc1, 0x8b, 0xe7, 0x6c, 0x05, 0x4e, 0xc2, 0xc3, 0xc3, + 0x87, 0x1c, 0xd3, 0x0b, 0x0a, 0x0a, 0xe0, 0x35, 0x86, 0xfb, 0x93, 0x62, + 0xd3, 0x99, 0xe1, 0xe1, 0x45, 0xdf, 0x46, 0x9c, 0x11, 0xb1, 0x1e, 0xd9, + 0x14, 0x62, 0x90, 0xd2, 0xf4, 0xf7, 0xd7, 0xc1, 0xf0, 0xe8, 0xb4, 0x34, + 0x9a, 0xe4, 0xc1, 0x8a, 0x0a, 0xde, 0x48, 0x1a, 0xc1, 0x22, 0xef, 0xa6, + 0xb2, 0x32, 0xc2, 0xe7, 0x6f, 0xca, 0x9a, 0x4b, 0xf0, 0x9d, 0x47, 0x50, + 0x6f, 0xb6, 0x6e, 0xb7, 0xaf, 0x11, 0x4a, 0xc6, 0x0d, 0x82, 0x48, 0x89, + 0x8b, 0x07, 0xd6, 0xb9, 0x50, 0xa1, 0x66, 0xe3, 0x4e, 0x54, 0x9d, 0x7a, + 0x10, 0x12, 0x69, 0x61, 0x0e, 0x58, 0x0d, 0xa6, 0x34, 0xac, 0x29, 0x63, + 0xfc, 0xb0, 0xc7, 0x97, 0x7c, 0xb9, 0x2d, 0x2b, 0x2b, 0x9b, 0x2c, 0xf8, + 0x83, 0x4b, 0x50, 0x30, 0x11, 0x3f, 0x68, 0x45, 0x42, 0xa7, 0x74, 0x64, + 0xf4, 0xb0, 0xd1, 0x7f, 0xd0, 0xcf, 0x1e, 0x08, 0x72, 0x77, 0x9f, 0x82, + 0x82, 0xc4, 0x1e, 0xf6, 0x77, 0xfb, 0xd5, 0xc9, 0x04, 0x49, 0x71, 0xf1, + 0x26, 0x5d, 0x39, 0xbd, 0x42, 0x9d, 0xfd, 0x5d, 0x3a, 0xcf, 0xcd, 0x9f, + 0xd4, 0x52, 0xe6, 0xed, 0xa0, 0x64, 0x18, 0x35, 0xfe, 0x6d, 0x9d, 0x6b, + 0x66, 0x0a, 0x8a, 0x6a, 0xa0, 0xf1, 0x93, 0x36, 0x0c, 0x48, 0x12, 0xc7, + 0xa1, 0xca, 0x6d, 0x24, 0xfc, 0x7e, 0x01, 0x3e, 0xda, 0xc0, 0xb2, 0x41, + 0xcc, 0xac, 0x68, 0x2c, 0x90, 0xda, 0xd7, 0xdd, 0x7d, 0xb4, 0xb2, 0x62, + 0x9e, 0xbc, 0x0e, 0xea, 0xc8, 0xd6, 0x8b, 0xa1, 0xcf, 0x9b, 0x09, 0x65, + 0x45, 0x45, 0x56, 0xd7, 0xd2, 0x32, 0xa3, 0x3d, 0xc5, 0x8c, 0x86, 0x26, + 0xa1, 0x4c, 0xaf, 0x78, 0xe3, 0xc3, 0xc5, 0x9e, 0x8b, 0xca, 0x48, 0x7e, + 0x7e, 0x7e, 0x33, 0xc0, 0x06, 0xdc, 0x03, 0xde, 0x77, 0xd7, 0xe7, 0xa5, + 0xf1, 0xf5, 0x3d, 0x16, 0xab, 0xa9, 0xa9, 0xa9, 0xb7, 0xf9, 0xc9, 0xa6, + 0xae, 0x3b, 0x8f, 0x42, 0x37, 0x7f, 0x37, 0x70, 0x9b, 0x54, 0x12, 0xa9, + 0xa2, 0x52, 0x29, 0x96, 0x68, 0xdf, 0xcd, 0xd2, 0x4b, 0xf0, 0xd2, 0x36, + 0xc3, 0xcc, 0xa4, 0x0b, 0xf8, 0x97, 0x61, 0xcf, 0xfd, 0xb9, 0x29, 0x09, + 0xa1, 0xbb, 0x9d, 0x82, 0x4c, 0x0f, 0x95, 0x11, 0xc3, 0xd2, 0x24, 0x1e, + 0x93, 0xc6, 0x2f, 0x01, 0x40, 0x42, 0x6f, 0x9b, 0x0e, 0x5b, 0xd7, 0x1f, + 0xae, 0xa7, 0xdb, 0xbc, 0x14, 0x14, 0x14, 0x8a, 0x59, 0x0e, 0x6e, 0x99, + 0x55, 0xb2, 0x0f, 0x9f, 0x9e, 0xe2, 0xe2, 0x02, 0xf5, 0xe3, 0xc8, 0xac, + 0x5a, 0xaa, 0xf5, 0xb2, 0x15, 0x2f, 0x6c, 0xf8, 0x70, 0x72, 0x5c, 0x44, + 0x87, 0x8b, 0x85, 0x05, 0x11, 0x91, 0x33, 0x63, 0x5d, 0xd5, 0x7a, 0x15, + 0xf3, 0xd6, 0xc8, 0x7c, 0xc5, 0xc8, 0x3f, 0xfd, 0xae, 0x10, 0x55, 0x67, + 0x8e, 0x2a, 0xe0, 0x27, 0xbd, 0xbc, 0xd6, 0x0e, 0xa6, 0x1a, 0x35, 0x30, + 0x7f, 0x01, 0x1b, 0x05, 0x17, 0x30, 0x2b, 0x1c, 0xc5, 0x0e, 0x2f, 0x80, + 0xdd, 0x87, 0x3f, 0x6a, 0xb3, 0x0e, 0x06, 0x5a, 0xff, 0x1a, 0x64, 0xfe, + 0x13, 0x1b, 0x19, 0x9a, 0xce, 0x47, 0x68, 0x1b, 0x0e, 0xd2, 0x95, 0xc8, + 0x2a, 0x92, 0xa7, 0xfd, 0x8c, 0xe4, 0x33, 0x11, 0x85, 0xc9, 0xe2, 0x9f, + 0x5d, 0x1f, 0x43, 0xc2, 0xfd, 0xa8, 0x80, 0x7f, 0x40, 0x80, 0xa0, 0xd0, + 0x88, 0x97, 0x4c, 0xcf, 0x34, 0xf3, 0x69, 0x04, 0x54, 0xc1, 0x9d, 0x07, + 0x60, 0xc4, 0x7d, 0x0b, 0xf3, 0x93, 0x0c, 0x0a, 0xda, 0x77, 0xee, 0xf1, + 0x64, 0xe7, 0x22, 0xb0, 0x10, 0xf2, 0x40, 0x1f, 0x71, 0xd8, 0x1c, 0x3c, + 0xd0, 0x12, 0xdd, 0xcd, 0x20, 0xf2, 0x5c, 0x9f, 0x8c, 0x4c, 0x40, 0x54, + 0x67, 0x76, 0x1b, 0x17, 0x95, 0x3e, 0x1c, 0x88, 0xe9, 0xce, 0x03, 0x06, + 0xa9, 0xbf, 0x33, 0x86, 0xa4, 0x12, 0x51, 0x3d, 0x08, 0xf8, 0x53, 0x79, + 0xa9, 0xa1, 0x50, 0x26, 0x67, 0x1e, 0xf4, 0xff, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x93, 0x8b, 0x92, 0x0e, 0x50, 0xb2, 0x00, 0x00, + })) + + if err != nil { + panic("Decompression failed: " + err.Error()) + } + + var b bytes.Buffer + io.Copy(&b, gz) + gz.Close() + + return b.Bytes() +} diff --git a/vend/xgbutil/icccm/doc.go b/vend/xgbutil/icccm/doc.go new file mode 100644 index 0000000..0aa16ea --- /dev/null +++ b/vend/xgbutil/icccm/doc.go @@ -0,0 +1,61 @@ +/* +Package icccm provides an API for a portion of the ICCCM, namely, getters +and setters for many of the properties specified in the ICCCM. There is also a +smattering of support for other protocols specified by ICCCM. For example, to +satisfy the WM_DELETE_WINDOW protocol, package icccm provides 'IsDeleteProtocol' +which returns whether a ClientMessage event satisfies the WM_DELETE_WINDOW +protocol. + +If a property has values that aren't simple strings or integers, struct types +are provided to organize the data. In particular, WM_NORMAL_HINTS and WM_HINTS. + +Also note that properties like WM_NORMAL_HINTS and WM_HINTS contain a 'Flags' +field (a bit mask) that specifies which values are "active". This is of +importance when setting and reading WM_NORMAL_HINTS and WM_HINTS; one must make +sure the appropriate bit is set in Flags. + +For example, you might want to check if a window has specified a resize +increment in the WM_NORMAL_HINTS property. The values in the corresponding +NormalHints struct are WidthInc and HeightInc. So to check if such values exist +*and* should be used: + + normalHints, err := icccm.WmNormalHintsGet(XUtilValue, window-id) + if err != nil { + // handle error + } + if normalHints.Flags&icccm.SizeHintPResizeInc > 0 { + // Use normalHints.WidthInc and normalHints.HeightInc + } + +When you should use icccm + +Although the ICCCM is extremely old, a lot of it is still used. In fact, the +EWMH spec itself specifically states that the ICCCM should still be used unless +otherwise noted by the EWMH. For example, WM_HINTS and WM_NORMAL_HINTS are +still used, but _NET_WM_NAME replaces WM_NAME. + +With that said, many applications (like xterm or LibreOffice) have not been +updated to be fully EWMH compliant. Therefore, code that finds a window's name +often looks like this: + + winName, err := ewmh.WmNameGet(XUtilValue, window-id) + if err != nil || winName == "" { + winName, err = icccm.WmNameGet(XUtilValue, window-id) + if err != nill || winName == "" { + winName = "N/A" + } + } + +Something similar can be said for the _NET_WM_ICON and the IconPixmap field +in WM_HINTS. + +Naming scheme + +The naming scheme is precisely the same as the one found in the ewmh package. +The documentation for the ewmh package describes the naming scheme in more +detail. The only difference (currently) is that the icccm package only contains +functions ending in "Get" and "Set". It is planned to add "Req" functions. (An +example of a Req function would be to send a ClientMessage implementing the +WM_DELETE_WINDOW protocol to a client window.) +*/ +package icccm diff --git a/vend/xgbutil/icccm/icccm.go b/vend/xgbutil/icccm/icccm.go new file mode 100644 index 0000000..e7a6293 --- /dev/null +++ b/vend/xgbutil/icccm/icccm.go @@ -0,0 +1,358 @@ +package icccm + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xprop" +) + +const ( + HintInput = (1 << iota) + HintState + HintIconPixmap + HintIconWindow + HintIconPosition + HintIconMask + HintWindowGroup + HintMessage + HintUrgency +) + +const ( + SizeHintUSPosition = (1 << iota) + SizeHintUSSize + SizeHintPPosition + SizeHintPSize + SizeHintPMinSize + SizeHintPMaxSize + SizeHintPResizeInc + SizeHintPAspect + SizeHintPBaseSize + SizeHintPWinGravity +) + +const ( + StateWithdrawn = iota + StateNormal + StateZoomed + StateIconic + StateInactive +) + +// WM_NAME get +func WmNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { + return xprop.PropValStr(xprop.GetProperty(xu, win, "WM_NAME")) +} + +// WM_NAME set +func WmNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { + return xprop.ChangeProp(xu, win, 8, "WM_NAME", "STRING", ([]byte)(name)) +} + +// WM_ICON_NAME get +func WmIconNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { + return xprop.PropValStr(xprop.GetProperty(xu, win, "WM_ICON_NAME")) +} + +// WM_ICON_NAME set +func WmIconNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { + return xprop.ChangeProp(xu, win, 8, "WM_ICON_NAME", "STRING", + ([]byte)(name)) +} + +// NormalHints is a struct that organizes the information related to the +// WM_NORMAL_HINTS property. Please see the ICCCM spec for more details. +type NormalHints struct { + Flags uint + X, Y int + Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight uint + WidthInc, HeightInc uint + MinAspectNum, MinAspectDen, MaxAspectNum, MaxAspectDen uint + BaseWidth, BaseHeight, WinGravity uint +} + +// WM_NORMAL_HINTS get +func WmNormalHintsGet(xu *xgbutil.XUtil, + win xproto.Window) (nh *NormalHints, err error) { + + lenExpect := 18 + hints, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "WM_NORMAL_HINTS")) + if err != nil { + return nil, err + } + if len(hints) != lenExpect { + return nil, + fmt.Errorf("WmNormalHint: There are %d fields in WM_NORMAL_HINTS, "+ + "but xgbutil expects %d.", len(hints), lenExpect) + } + + nh = &NormalHints{} + nh.Flags = hints[0] + nh.X = int(hints[1]) + nh.Y = int(hints[2]) + nh.Width = hints[3] + nh.Height = hints[4] + nh.MinWidth = hints[5] + nh.MinHeight = hints[6] + nh.MaxWidth = hints[7] + nh.MaxHeight = hints[8] + nh.WidthInc = hints[9] + nh.HeightInc = hints[10] + nh.MinAspectNum = hints[11] + nh.MinAspectDen = hints[12] + nh.MaxAspectNum = hints[13] + nh.MaxAspectDen = hints[14] + nh.BaseWidth = hints[15] + nh.BaseHeight = hints[16] + nh.WinGravity = hints[17] + + if nh.WinGravity <= 0 { + nh.WinGravity = xproto.GravityNorthWest + } + + return nh, nil +} + +// WM_NORMAL_HINTS set +// Make sure to set the flags in the NormalHints struct correctly! +func WmNormalHintsSet(xu *xgbutil.XUtil, win xproto.Window, + nh *NormalHints) error { + + raw := []uint{ + nh.Flags, + uint(nh.X), uint(nh.Y), nh.Width, nh.Height, + nh.MinWidth, nh.MinHeight, + nh.MaxWidth, nh.MaxHeight, + nh.WidthInc, nh.HeightInc, + nh.MinAspectNum, nh.MinAspectDen, + nh.MaxAspectNum, nh.MaxAspectDen, + nh.BaseWidth, nh.BaseHeight, + nh.WinGravity, + } + return xprop.ChangeProp32(xu, win, "WM_NORMAL_HINTS", "WM_SIZE_HINTS", + raw...) +} + +// Hints is a struct that organizes information related to the WM_HINTS +// property. Once again, I refer you to the ICCCM spec for documentation. +type Hints struct { + Flags uint + Input, InitialState uint + IconX, IconY int + IconPixmap, IconMask xproto.Pixmap + WindowGroup, IconWindow xproto.Window +} + +// WM_HINTS get +func WmHintsGet(xu *xgbutil.XUtil, + win xproto.Window) (hints *Hints, err error) { + + lenExpect := 9 + raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_HINTS")) + if err != nil { + return nil, err + } + if len(raw) != lenExpect { + return nil, + fmt.Errorf("WmHints: There are %d fields in "+ + "WM_HINTS, but xgbutil expects %d.", len(raw), lenExpect) + } + + hints = &Hints{} + hints.Flags = raw[0] + hints.Input = raw[1] + hints.InitialState = raw[2] + hints.IconPixmap = xproto.Pixmap(raw[3]) + hints.IconWindow = xproto.Window(raw[4]) + hints.IconX = int(raw[5]) + hints.IconY = int(raw[6]) + hints.IconMask = xproto.Pixmap(raw[7]) + hints.WindowGroup = xproto.Window(raw[8]) + + return hints, nil +} + +// WM_HINTS set +// Make sure to set the flags in the Hints struct correctly! +func WmHintsSet(xu *xgbutil.XUtil, win xproto.Window, hints *Hints) error { + raw := []uint{ + hints.Flags, hints.Input, hints.InitialState, + uint(hints.IconPixmap), uint(hints.IconWindow), + uint(hints.IconX), uint(hints.IconY), + uint(hints.IconMask), + uint(hints.WindowGroup), + } + return xprop.ChangeProp32(xu, win, "WM_HINTS", "WM_HINTS", raw...) +} + +// WmClass struct contains two data points: +// the instance and a class of a window. +type WmClass struct { + Instance, Class string +} + +// WM_CLASS get +func WmClassGet(xu *xgbutil.XUtil, win xproto.Window) (*WmClass, error) { + raw, err := xprop.PropValStrs(xprop.GetProperty(xu, win, "WM_CLASS")) + if err != nil { + return nil, err + } + if len(raw) != 2 { + return nil, + fmt.Errorf("WmClass: Two string make up WM_CLASS, but "+ + "xgbutil found %d in '%v'.", len(raw), raw) + } + + return &WmClass{ + Instance: raw[0], + Class: raw[1], + }, nil +} + +// WM_CLASS set +func WmClassSet(xu *xgbutil.XUtil, win xproto.Window, class *WmClass) error { + raw := make([]byte, len(class.Instance)+len(class.Class)+2) + copy(raw, class.Instance) + copy(raw[(len(class.Instance)+1):], class.Class) + + return xprop.ChangeProp(xu, win, 8, "WM_CLASS", "STRING", raw) +} + +// WM_TRANSIENT_FOR get +func WmTransientForGet(xu *xgbutil.XUtil, + win xproto.Window) (xproto.Window, error) { + + return xprop.PropValWindow(xprop.GetProperty(xu, win, "WM_TRANSIENT_FOR")) +} + +// WM_TRANSIENT_FOR set +func WmTransientForSet(xu *xgbutil.XUtil, win xproto.Window, + transient xproto.Window) error { + + return xprop.ChangeProp32(xu, win, "WM_TRANSIENT_FOR", "WINDOW", + uint(transient)) +} + +// WM_PROTOCOLS get +func WmProtocolsGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { + raw, err := xprop.GetProperty(xu, win, "WM_PROTOCOLS") + return xprop.PropValAtoms(xu, raw, err) +} + +// WM_PROTOCOLS set +func WmProtocolsSet(xu *xgbutil.XUtil, win xproto.Window, + atomNames []string) error { + + atoms, err := xprop.StrToAtoms(xu, atomNames) + if err != nil { + return err + } + return xprop.ChangeProp32(xu, win, "WM_PROTOCOLS", "ATOM", atoms...) +} + +// WM_COLORMAP_WINDOWS get +func WmColormapWindowsGet(xu *xgbutil.XUtil, + win xproto.Window) ([]xproto.Window, error) { + + return xprop.PropValWindows(xprop.GetProperty(xu, win, + "WM_COLORMAP_WINDOWS")) +} + +// WM_COLORMAP_WINDOWS set +func WmColormapWindowsSet(xu *xgbutil.XUtil, win xproto.Window, + windows []xproto.Window) error { + + return xprop.ChangeProp32(xu, win, "WM_COLORMAP_WINDOWS", "WINDOW", + xprop.WindowToInt(windows)...) +} + +// WM_CLIENT_MACHINE get +func WmClientMachineGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { + return xprop.PropValStr(xprop.GetProperty(xu, win, "WM_CLIENT_MACHINE")) +} + +// WM_CLIENT_MACHINE set +func WmClientMachineSet(xu *xgbutil.XUtil, win xproto.Window, + client string) error { + + return xprop.ChangeProp(xu, win, 8, "WM_CLIENT_MACHINE", "STRING", + ([]byte)(client)) +} + +// WmState is a struct that organizes information related to the WM_STATE +// property. Namely, the state (corresponding to a State* constant in this file) +// and the icon window (probably not used). +type WmState struct { + State uint + Icon xproto.Window +} + +// WM_STATE get +func WmStateGet(xu *xgbutil.XUtil, win xproto.Window) (*WmState, error) { + raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_STATE")) + if err != nil { + return nil, err + } + if len(raw) != 2 { + return nil, + fmt.Errorf("WmState: Expected two integers in WM_STATE property "+ + "but xgbutil found %d in '%v'.", len(raw), raw) + } + + return &WmState{ + State: raw[0], + Icon: xproto.Window(raw[1]), + }, nil +} + +// WM_STATE set +func WmStateSet(xu *xgbutil.XUtil, win xproto.Window, state *WmState) error { + raw := []uint{ + state.State, + uint(state.Icon), + } + + return xprop.ChangeProp32(xu, win, "WM_STATE", "WM_STATE", raw...) +} + +// IconSize is a struct the organizes information related to the WM_ICON_SIZE +// property. Mostly info about its dimensions. +type IconSize struct { + MinWidth, MinHeight, MaxWidth, MaxHeight, WidthInc, HeightInc uint +} + +// WM_ICON_SIZE get +func WmIconSizeGet(xu *xgbutil.XUtil, win xproto.Window) (*IconSize, error) { + raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_ICON_SIZE")) + if err != nil { + return nil, err + } + if len(raw) != 6 { + return nil, + fmt.Errorf("WmIconSize: Expected six integers in WM_ICON_SIZE "+ + "property, but xgbutil found "+"%d in '%v'.", len(raw), raw) + } + + return &IconSize{ + MinWidth: raw[0], MinHeight: raw[1], + MaxWidth: raw[2], MaxHeight: raw[3], + WidthInc: raw[4], HeightInc: raw[5], + }, nil +} + +// WM_ICON_SIZE set +func WmIconSizeSet(xu *xgbutil.XUtil, win xproto.Window, + icondim *IconSize) error { + + raw := []uint{ + icondim.MinWidth, icondim.MinHeight, + icondim.MaxWidth, icondim.MaxHeight, + icondim.WidthInc, icondim.HeightInc, + } + + return xprop.ChangeProp32(xu, win, "WM_ICON_SIZE", "WM_ICON_SIZE", raw...) +} diff --git a/vend/xgbutil/icccm/protocols.go b/vend/xgbutil/icccm/protocols.go new file mode 100644 index 0000000..98c2fd2 --- /dev/null +++ b/vend/xgbutil/icccm/protocols.go @@ -0,0 +1,64 @@ +package icccm + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xprop" +) + +// IsDeleteProtocol checks whether a ClientMessage event satisfies the +// WM_DELETE_WINDOW protocol. Namely, the format must be 32, the type must +// be the WM_PROTOCOLS atom, and the first data item must be the atom +// WM_DELETE_WINDOW. +// +// Note that if you're using the xwindow package, you should use the +// WMGracefulClose method instead of directly using IsDeleteProtocol. +func IsDeleteProtocol(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) bool { + // Make sure the Format is 32. (Meaning that each data item is + // 32 bits.) + if ev.Format != 32 { + return false + } + + // Check to make sure the Type atom is WM_PROTOCOLS. + typeName, err := xprop.AtomName(X, ev.Type) + if err != nil || typeName != "WM_PROTOCOLS" { // not what we want + return false + } + + // Check to make sure the first data item is WM_DELETE_WINDOW. + protocolType, err := xprop.AtomName(X, + xproto.Atom(ev.Data.Data32[0])) + if err != nil || protocolType != "WM_DELETE_WINDOW" { + return false + } + + return true +} + +// IsFocusProtocol checks whether a ClientMessage event satisfies the +// WM_TAKE_FOCUS protocol. +func IsFocusProtocol(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) bool { + // Make sure the Format is 32. (Meaning that each data item is + // 32 bits.) + if ev.Format != 32 { + return false + } + + // Check to make sure the Type atom is WM_PROTOCOLS. + typeName, err := xprop.AtomName(X, ev.Type) + if err != nil || typeName != "WM_PROTOCOLS" { // not what we want + return false + } + + // Check to make sure the first data item is WM_TAKE_FOCUS. + protocolType, err := xprop.AtomName(X, + xproto.Atom(ev.Data.Data32[0])) + if err != nil || protocolType != "WM_TAKE_FOCUS" { + return false + } + + return true +} diff --git a/vend/xgbutil/keybind/callback.go b/vend/xgbutil/keybind/callback.go new file mode 100644 index 0000000..6bb0c92 --- /dev/null +++ b/vend/xgbutil/keybind/callback.go @@ -0,0 +1,161 @@ +package keybind + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" +) + +// connect is essentially 'Connect' for either KeyPress or KeyRelease events. +// Namely, it parses the key string, issues a grab request if necessary, +// sets up the appropriate event handlers for the main event loop, and attaches +// the callback to the keybinding state. +func connect(xu *xgbutil.XUtil, callback xgbutil.CallbackKey, + evtype int, win xproto.Window, keyStr string, grab, reconnect bool) error { + + // Get the mods/key first + mods, keycodes, err := ParseString(xu, keyStr) + if err != nil { + return err + } + + // Only do the grab if we haven't yet on this window. + for _, keycode := range keycodes { + if grab && keyBindGrabs(xu, evtype, win, mods, keycode) == 0 { + if err := GrabChecked(xu, win, mods, keycode); err != nil { + // If a bad access, let's be nice and give a good error message. + switch err.(type) { + case xproto.AccessError: + return fmt.Errorf("Got a bad access error when trying to "+ + "bind '%s'. This usually means another client has "+ + "already grabbed this keybinding.", keyStr) + default: + return fmt.Errorf("Could not bind '%s' because: %s", + keyStr, err) + } + } + } + + // If we've never grabbed anything on this window before, we need to + // make sure we can respond to it in the main event loop. + // Never do this if we're reconnecting. + if !reconnect { + var allCb xgbutil.Callback + if evtype == xevent.KeyPress { + allCb = xevent.KeyPressFun(runKeyPressCallbacks) + } else { + allCb = xevent.KeyReleaseFun(runKeyReleaseCallbacks) + } + + // If this is the first Key{Press|Release}Event on this window, + // then we need to listen to Key{Press|Release} events in the main + // loop. + if !connectedKeyBind(xu, evtype, win) { + allCb.Connect(xu, win) + } + } + + // Finally, attach the callback. + attachKeyBindCallback(xu, evtype, win, mods, keycode, callback) + } + + // Keep track of all unique key connections. + if !reconnect { + addKeyString(xu, callback, evtype, win, keyStr, grab) + } + + return nil +} + +// DeduceKeyInfo AND's the "ignored modifiers" out of the state returned by +// a Key{Press,Release} event. This is useful to connect a (state, keycode) +// tuple from an event with a tuple specified by the user. +func DeduceKeyInfo(state uint16, + detail xproto.Keycode) (uint16, xproto.Keycode) { + + mods, kc := state, detail + for _, m := range xevent.IgnoreMods { + mods &= ^m + } + return mods, kc +} + +// KeyPressFun represents a function that is called when a particular key +// binding is fired. +type KeyPressFun xevent.KeyPressFun + +func (callback KeyPressFun) Connect(xu *xgbutil.XUtil, win xproto.Window, + keyStr string, grab bool) error { + + return connect(xu, callback, xevent.KeyPress, win, keyStr, grab, false) +} + +func (callback KeyPressFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(xevent.KeyPressEvent)) +} + +// KeyReleaseFun represents a function that is called when a particular key +// binding is fired. +type KeyReleaseFun xevent.KeyReleaseFun + +func (callback KeyReleaseFun) Connect(xu *xgbutil.XUtil, win xproto.Window, + keyStr string, grab bool) error { + + return connect(xu, callback, xevent.KeyRelease, win, keyStr, grab, false) +} + +func (callback KeyReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(xevent.KeyReleaseEvent)) +} + +// runKeyPressCallbacks infers the window, keycode and modifiers from a +// KeyPressEvent and runs the corresponding callbacks. +func runKeyPressCallbacks(xu *xgbutil.XUtil, ev xevent.KeyPressEvent) { + mods, kc := DeduceKeyInfo(ev.State, ev.Detail) + + runKeyBindCallbacks(xu, ev, xevent.KeyPress, ev.Event, mods, kc) +} + +// runKeyReleaseCallbacks infers the window, keycode and modifiers from a +// KeyPressEvent and runs the corresponding callbacks. +func runKeyReleaseCallbacks(xu *xgbutil.XUtil, ev xevent.KeyReleaseEvent) { + mods, kc := DeduceKeyInfo(ev.State, ev.Detail) + + runKeyBindCallbacks(xu, ev, xevent.KeyRelease, ev.Event, mods, kc) +} + +// Detach removes all handlers for all key events for the provided window id. +// This should be called whenever a window is no longer receiving events to make +// sure the garbage collector can release memory used to store the handler info. +func Detach(xu *xgbutil.XUtil, win xproto.Window) { + detach(xu, xevent.KeyPress, win) + detach(xu, xevent.KeyRelease, win) +} + +// DetachPress is the same as Detach, except it only removes handlers for +// key *press* events. +func DetachPress(xu *xgbutil.XUtil, win xproto.Window) { + detach(xu, xevent.KeyPress, win) +} + +// DetachRelease is the same as Detach, except it only removes handlers for +// key *release* events. +func DetachRelease(xu *xgbutil.XUtil, win xproto.Window) { + detach(xu, xevent.KeyRelease, win) +} + +// detach removes all handlers for the provided window and event type +// combination. This will also issue an ungrab request for each grab that +// drops to zero. +func detach(xu *xgbutil.XUtil, evtype int, win xproto.Window) { + mkeys := keyKeys(xu) + detachKeyBindWindow(xu, evtype, win) + for _, key := range mkeys { + if keyBindGrabs(xu, key.Evtype, key.Win, key.Mod, key.Code) == 0 { + Ungrab(xu, key.Win, key.Mod, key.Code) + } + } +} diff --git a/vend/xgbutil/keybind/doc.go b/vend/xgbutil/keybind/doc.go new file mode 100644 index 0000000..48929c4 --- /dev/null +++ b/vend/xgbutil/keybind/doc.go @@ -0,0 +1,129 @@ +/* +Package keybind provides an easy to use interface to assign callback functions +to human readable key sequences. + +Working with the X keyboard encoding is not an easy task, and the keybind +package attempts to encapsulate much of the complexity. Namely, the keybind +package exports two function types: KeyPressFun and KeyReleaseFun. Values of +these types are functions, and have a method called 'Connect' that attaches +an event handler to be run when a particular key press is issued. + +This is virtually identical to the way calbacks are attached using the xevent +package, but the Connect method in the keybind package has a couple extra +parameters that are specific to key bindings. Namely, the key sequence to +respond to (which is a combination of zero or more modifiers and exactly one +key) and whether to establish a passive grab. One can still attach callbacks +to Key{Press,Release} events using xevent, but it will be run for *all* +Key{Press,Release} events. (This is typically what one might do when setting up +an active grab.) + +Initialization + +Before using the keybind package, you should *always* make a single call to +keybind.Initialize for each X connection you're working with. + +Key sequence format + +Key sequences are human readable strings made up of zero or more modifiers and +exactly one key. Namely: + + [Mod[-Mod[...]]-]KEY + +Where 'Mod' can be one of: shift, lock, control, mod1, mod2, mod3, mod4, mod5, +or any. You can view which keys activate each modifier using the 'xmodmap' +program. (If you don't have 'xmodmap', you could also run the 'xmodmap' example +in the examples directory.) + +KEY must correspond to a valid keysym. Keysyms can be found by pressing keys +using the 'xev' program. Alternatively, you may inspect the 'keysyms' map in +xgbutil/keybind/keysymdef.go. + +An example key sequence might look like 'Mod4-Control-Shift-t'. The keybinding +for that key sequence is activated when all three modifiers---mod4, control and +shift---are pressed along with the 't' key. + +When to issue a passive grab + +One of the parameters of the 'Connect' method is whether to issue a passive +grab or not. A passive grab is useful when you need to respond to a key press +on some parent window (like the root window) without actually focusing that +window. Not using a passive grab is useful when you only need to read key +presses when the window is focused. + +For more information on the semantics of passive grabs, please see +http://tronche.com/gui/x/xlib/input/XGrabKey.html. + +Also, by default, when issuing a grab on a particular (modifiers, keycode) +tuple, several grabs are actually made. In particular, for each grab requested, +another grab is made with the "num lock" mask, another grab is made with the +"caps lock" mask, and another grab is made with both the "num lock" and "caps +locks" masks. This allows key events to be reported regardless of whether +caps lock or num lock is enabled. + +The extra masks added can be modified by changing the xevent.IgnoreMods slice. +If you modify xevent.IgnoreMods, it should be modified once on program startup +(i.e., before any key or mouse bindings are established) and never modified +again. + +Key bindings on the root window example + +To run a particular function whenever the 'Mod4-Control-Shift-t' key +combination is pressed (mod4 is typically the 'super' or 'windows' key, but can +vary based on your system), use something like: + + keybind.Initialize(XUtilValue) // call once before using keybind package + keybind.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + // do something when key is pressed + }).Connect(XUtilValue, XUtilValue.RootWin(), + "Mod4-Control-Shift-t", true) + +Note that we issue a passive grab because Key{Press,Release} events on the root +window will only be reported when the root window has focus if no grab exists. + +Key bindings on a window you create example + +This code snippet attaches an event handler to some window you've created +without using a grab. Thus, the function will only be activated when the key +sequence is pressed and your window has focus. + + keybind.Initialize(XUtilValue) // call once before using keybind package + keybind.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + // do something when key is pressed + }).Connect(XUtilValue, your-window-id, "Mod4-t", false) + +Run a function on all key press events example + +This code snippet actually does *not* use the keybind package, but illustrates +how the Key{Press,Release} event handlers in the xevent package can still be +useful. Namely, the keybind package discriminates among events depending upon +the key sequences pressed, whereas the xevent package is more general: it can +only discriminate at the event level. + + xevent.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + // do something when any key is pressed + }).Connect(XUtilValue, your-window-id) + +This is the kind of handler you might use to capture all key press events. +(i.e., if you have a text box for a user to type in.) Additionally, if you're +using this sort of event handler, keybind.LookupString will probably be of some +use. Its contract is that given a (modifiers, keycode) tuple +(information found in all Key{Press,Release} events) it will return a string +representation of the key pressed. We can modify the above example slightly to +echo the key pressed: + + xevent.KeyPressFun( + func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { + fmt.Println("Key pressed:", + keybind.LookupString(X, ev.State, ev.Detail)) + }).Connect(XUtilValue, your-window-id) + +More examples + +Complete working examples can be found in the examples directory of xgbutil. Of +particular interest are probably 'keypress-english' and 'simple-keybinding'. + +*/ +package keybind diff --git a/vend/xgbutil/keybind/encoding.go b/vend/xgbutil/keybind/encoding.go new file mode 100644 index 0000000..4af8ee2 --- /dev/null +++ b/vend/xgbutil/keybind/encoding.go @@ -0,0 +1,128 @@ +package keybind + +/* +This file contains the logic to implement X's Keyboard Encoding +described here: http://goo.gl/qum9q + +Essentially, LookupString is analogous to Xlib's XLookupString. It's useful +in determining the english string representation of modifiers + keycode. + +It is not for the faint of heart. +*/ + +import ( + "strings" + "unicode" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// LookupString attempts to convert a (modifiers, keycode) to an english string. +// It essentially implements the rules described at http://goo.gl/qum9q +// Namely, the bulleted list that describes how key syms should be interpreted +// when various modifiers are pressed. +// Note that we ignore the logic that asks us to check if particular key codes +// are mapped to particular modifiers (i.e., "XK_Caps_Lock" to "Lock" modifier). +// We just check if the modifiers are activated. That's good enough for me. +// XXX: We ignore num lock stuff. +// XXX: We ignore MODE SWITCH stuff. (i.e., we don't use group 2 key syms.) +func LookupString(xu *xgbutil.XUtil, mods uint16, + keycode xproto.Keycode) string { + + k1, k2, _, _ := interpretSymList(xu, keycode) + + shift := mods&xproto.ModMaskShift > 0 + lock := mods&xproto.ModMaskLock > 0 + switch { + case !shift && !lock: + return k1 + case !shift && lock: + if len(k1) == 1 && unicode.IsLower(rune(k1[0])) { + return k2 + } else { + return k1 + } + case shift && lock: + if len(k2) == 1 && unicode.IsLower(rune(k2[0])) { + return string(unicode.ToUpper(rune(k2[0]))) + } else { + return k2 + } + case shift: + return k2 + } + + return "" +} + +// ModifierString takes in a keyboard state and returns a string of all +// modifiers in the state. +func ModifierString(mods uint16) string { + modStrs := make([]string, 0, 3) + for i, mod := range Modifiers { + if mod&mods > 0 && len(NiceModifiers[i]) > 0 { + modStrs = append(modStrs, NiceModifiers[i]) + } + } + return strings.Join(modStrs, "-") +} + +// KeyMatch returns true if a string representation of a key can +// be matched (case insensitive) to the (modifiers, keycode) tuple provided. +// String representations can be found in keybind/keysymdef.go +func KeyMatch(xu *xgbutil.XUtil, + keyStr string, mods uint16, keycode xproto.Keycode) bool { + + guess := LookupString(xu, mods, keycode) + return strings.ToLower(guess) == strings.ToLower(keyStr) +} + +// interpretSymList interprets the keysym list for a particular keycode as +// described in the third and fourth paragraphs of http://goo.gl/qum9q +func interpretSymList(xu *xgbutil.XUtil, keycode xproto.Keycode) ( + k1 string, k2 string, k3 string, k4 string) { + + ks1 := KeysymGet(xu, keycode, 0) + ks2 := KeysymGet(xu, keycode, 1) + ks3 := KeysymGet(xu, keycode, 2) + ks4 := KeysymGet(xu, keycode, 3) + + // follow the rules, third paragraph + switch { + case ks2 == 0 && ks3 == 0 && ks4 == 0: + ks3 = ks1 + case ks3 == 0 && ks4 == 0: + ks3 = ks1 + ks4 = ks2 + case ks4 == 0: + ks4 = 0 + } + + // Now convert keysyms to strings, so we can do alphabetic shit. + k1 = KeysymToStr(ks1) + k2 = KeysymToStr(ks2) + k3 = KeysymToStr(ks3) + k4 = KeysymToStr(ks4) + + // follow the rules, fourth paragraph + if k2 == "" { + if len(k1) == 1 && unicode.IsLetter(rune(k1[0])) { + k1 = string(unicode.ToLower(rune(k1[0]))) + k2 = string(unicode.ToUpper(rune(k1[0]))) + } else { + k2 = k1 + } + } + if k4 == "" { + if len(k3) == 1 && unicode.IsLetter(rune(k3[0])) { + k3 = string(unicode.ToLower(rune(k3[0]))) + k4 = string(unicode.ToUpper(rune(k4[0]))) + } else { + k4 = k3 + } + } + + return +} diff --git a/vend/xgbutil/keybind/keybind.go b/vend/xgbutil/keybind/keybind.go new file mode 100644 index 0000000..1279abf --- /dev/null +++ b/vend/xgbutil/keybind/keybind.go @@ -0,0 +1,386 @@ +package keybind + +import ( + "fmt" + "strings" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" +) + +var ( + Modifiers []uint16 = []uint16{ // order matters! + xproto.ModMaskShift, xproto.ModMaskLock, xproto.ModMaskControl, + xproto.ModMask1, xproto.ModMask2, xproto.ModMask3, + xproto.ModMask4, xproto.ModMask5, + xproto.ModMaskAny, + } + + NiceModifiers = []string{ + "shift", "lock", "control", "mod1", "mod2", "mod3", "mod4", "mod5", "", + } +) + +// Initialize attaches the appropriate callbacks to make key bindings easier. +// i.e., update state of the world on a MappingNotify. +func Initialize(xu *xgbutil.XUtil) { + // Listen to mapping notify events + xevent.MappingNotifyFun(updateMaps).Connect(xu, xevent.NoWindow) + + // Give us an initial mapping state... + keyMap, modMap := MapsGet(xu) + KeyMapSet(xu, keyMap) + ModMapSet(xu, modMap) +} + +// updateMaps runs in response to MappingNotify events. +// It is responsible for making sure our view of the world's keyboard +// and modifier maps is correct. (Pointer mappings should be handled in +// a similar callback in the mousebind package.) +func updateMaps(xu *xgbutil.XUtil, e xevent.MappingNotifyEvent) { + keyMap, modMap := MapsGet(xu) + + // So we used to go through the old mapping and the new mapping and pick + // out precisely where there are changes. But after allowing for a + // one-to-many mapping from keysym to keycodes, this process became too + // complex. So we're going to bust out our hammer and rebind everything + // based on the initial key strings. + if e.Request == xproto.MappingKeyboard { + // We must ungrab everything first, in case two keys are being swapped. + keys := keyKeys(xu) + for _, key := range keys { + Ungrab(xu, key.Win, key.Mod, key.Code) + detach(xu, key.Evtype, key.Win) + } + + // Wipe the slate clean. + xu.KeybindsLck.Lock() + xu.Keybinds = make(map[xgbutil.KeyKey][]xgbutil.CallbackKey, len(keys)) + xu.Keygrabs = make(map[xgbutil.KeyKey]int, len(keys)) + keyStrs := xu.Keystrings + xu.KeybindsLck.Unlock() + + // Update our mappings before rebinding. + KeyMapSet(xu, keyMap) + ModMapSet(xu, modMap) + + // Now rebind everything in Keystrings + for _, ks := range keyStrs { + err := connect(xu, + ks.Callback, ks.Evtype, ks.Win, ks.Str, ks.Grab, true) + if err != nil { + xgbutil.Logger.Println(err) + } + } + } else { + // We don't have to do something with MappingModifier like we do with + // MappingKeyboard. This is due to us requiring that key strings use + // modifier names built into X. (i.e., the names seen in the output of + // `xmodmap`.) This means that the modifier mappings happen on the X + // server side, so we don't *typically* have to care what key is + // actually being pressed to trigger a modifier. (There are some + // exceptional cases, and when that happens, we simply query on-demand + // which keys are modifiers. See the RunKey{Press,Release}Callbacks + // functions in keybind/callback.go for the deets.) + KeyMapSet(xu, keyMap) + ModMapSet(xu, modMap) + } +} + +// minMaxKeycodeGet a simple accessor to the X setup info to return the +// minimum and maximum keycodes. They are typically 8 and 255, respectively. +func minMaxKeycodeGet(xu *xgbutil.XUtil) (xproto.Keycode, xproto.Keycode) { + return xu.Setup().MinKeycode, xu.Setup().MaxKeycode +} + +// A convenience function to grab the KeyboardMapping and ModifierMapping +// from X. We need to do this on startup (see Initialize) and whenever we +// get a MappingNotify event. +func MapsGet(xu *xgbutil.XUtil) (*xproto.GetKeyboardMappingReply, + *xproto.GetModifierMappingReply) { + + min, max := minMaxKeycodeGet(xu) + newKeymap, keyErr := xproto.GetKeyboardMapping(xu.Conn(), min, + byte(max-min+1)).Reply() + newModmap, modErr := xproto.GetModifierMapping(xu.Conn()).Reply() + + // If there are errors, we really need to panic. We just can't do + // any key binding without a mapping from the server. + if keyErr != nil { + panic(fmt.Sprintf("COULD NOT GET KEYBOARD MAPPING: %v\n"+ + "THIS IS AN UNRECOVERABLE ERROR.\n", + keyErr)) + } + if modErr != nil { + panic(fmt.Sprintf("COULD NOT GET MODIFIER MAPPING: %v\n"+ + "THIS IS AN UNRECOVERABLE ERROR.\n", + keyErr)) + } + + return newKeymap, newModmap +} + +// ParseString takes a string of the format '[Mod[-Mod[...]]]-KEY', +// i.e., 'Mod4-j', and returns a modifiers/keycode combo. +// An error is returned if the string is malformed, or if no valid KEY can +// be found. +// Valid values of KEY should include almost anything returned by pressing +// keys with the 'xev' program. Alternatively, you may reference the keys +// of the 'keysyms' map defined in keybind/keysymdef.go. +func ParseString( + xu *xgbutil.XUtil, s string) (uint16, []xproto.Keycode, error) { + + mods, kcs := uint16(0), []xproto.Keycode{} + for _, part := range strings.Split(s, "-") { + switch strings.ToLower(part) { + case "shift": + mods |= xproto.ModMaskShift + case "lock": + mods |= xproto.ModMaskLock + case "control": + mods |= xproto.ModMaskControl + case "mod1": + mods |= xproto.ModMask1 + case "mod2": + mods |= xproto.ModMask2 + case "mod3": + mods |= xproto.ModMask3 + case "mod4": + mods |= xproto.ModMask4 + case "mod5": + mods |= xproto.ModMask5 + case "any": + mods |= xproto.ModMaskAny + default: // a key code! + if len(kcs) == 0 { // only accept the first keycode we see + kcs = StrToKeycodes(xu, part) + } + } + } + + if len(kcs) == 0 { + return 0, nil, fmt.Errorf("Could not find a valid keycode in the "+ + "string '%s'. Key binding failed.", s) + } + + return mods, kcs, nil +} + +// StrToKeycodes is a wrapper around keycodesGet meant to make our search +// a bit more flexible if needed. (i.e., case-insensitive) +func StrToKeycodes(xu *xgbutil.XUtil, str string) []xproto.Keycode { + // Do some fancy case stuff before we give up. + sym, ok := keysyms[str] + if !ok { + sym, ok = keysyms[strings.Title(str)] + } + if !ok { + sym, ok = keysyms[strings.ToLower(str)] + } + if !ok { + sym, ok = keysyms[strings.ToUpper(str)] + } + + // If we don't know what 'str' is, return 0. + // There will probably be a bad access. We should do better than that... + if !ok { + return []xproto.Keycode{} + } + return keycodesGet(xu, sym) +} + +// keysymsPer gets the number of keysyms per keycode for the current key map. +func keysymsPer(xu *xgbutil.XUtil) int { + return int(KeyMapGet(xu).KeysymsPerKeycode) +} + +// Given a keysym, find all keycodes mapped to it in the current X environment. +// keybind.Initialize MUST have been called before using this function. +func keycodesGet(xu *xgbutil.XUtil, keysym xproto.Keysym) []xproto.Keycode { + min, max := minMaxKeycodeGet(xu) + keyMap := KeyMapGet(xu) + if keyMap == nil { + panic("keybind.Initialize must be called before using the keybind " + + "package.") + } + + var c byte + var keycode xproto.Keycode + keycodes := make([]xproto.Keycode, 0) + set := make(map[xproto.Keycode]bool, 0) + + for kc := int(min); kc <= int(max); kc++ { + keycode = xproto.Keycode(kc) + for c = 0; c < keyMap.KeysymsPerKeycode; c++ { + if keysym == KeysymGet(xu, keycode, c) && !set[keycode] { + keycodes = append(keycodes, keycode) + set[keycode] = true + } + } + } + return keycodes +} + +// KeysymToStr converts a keysym to a string if one is available. +// If one is found, KeysymToStr also checks the 'weirdKeysyms' map, which +// contains a map from multi-character strings to single character +// representations (i.e., 'braceleft' to '{'). +// If no match is found initially, an empty string is returned. +func KeysymToStr(keysym xproto.Keysym) string { + symStr, ok := strKeysyms[keysym] + if !ok { + return "" + } + + shortSymStr, ok := weirdKeysyms[symStr] + if ok { + return string(shortSymStr) + } + + return symStr +} + +// KeysymGet is a shortcut alias for 'KeysymGetWithMap' using the current +// keymap stored in XUtil. +// keybind.Initialize MUST have been called before using this function. +func KeysymGet(xu *xgbutil.XUtil, keycode xproto.Keycode, + column byte) xproto.Keysym { + + return KeysymGetWithMap(xu, KeyMapGet(xu), keycode, column) +} + +// KeysymGetWithMap uses the given key map and finds a keysym associated +// with the given keycode in the current X environment. +func KeysymGetWithMap(xu *xgbutil.XUtil, keyMap *xgbutil.KeyboardMapping, + keycode xproto.Keycode, column byte) xproto.Keysym { + + min, _ := minMaxKeycodeGet(xu) + i := (int(keycode)-int(min))*int(keyMap.KeysymsPerKeycode) + int(column) + + return keyMap.Keysyms[i] +} + +// ModGet finds the modifier currently associated with a given keycode. +// If a modifier doesn't exist for this keycode, then 0 is returned. +func ModGet(xu *xgbutil.XUtil, keycode xproto.Keycode) uint16 { + modMap := ModMapGet(xu) + + var i byte + for i = 0; int(i) < len(modMap.Keycodes); i++ { + if modMap.Keycodes[i] == keycode { + return Modifiers[i/modMap.KeycodesPerModifier] + } + } + return 0 +} + +// Grab grabs a key with mods on a particular window. +// This will also grab all combinations of modifiers found in xevent.IgnoreMods. +func Grab(xu *xgbutil.XUtil, win xproto.Window, + mods uint16, key xproto.Keycode) { + + for _, m := range xevent.IgnoreMods { + xproto.GrabKey(xu.Conn(), true, win, mods|m, key, + xproto.GrabModeAsync, xproto.GrabModeAsync) + } +} + +// GrabChecked Grabs a key with mods on a particular window. +// This is the same as Grab, except that it issue a checked request. +// Which means that an error could be returned and handled on the spot. +// (Checked requests are slower than unchecked requests.) +// This will also grab all combinations of modifiers found in xevent.IgnoreMods. +func GrabChecked(xu *xgbutil.XUtil, win xproto.Window, + mods uint16, key xproto.Keycode) error { + + var err error + for _, m := range xevent.IgnoreMods { + err = xproto.GrabKeyChecked(xu.Conn(), true, win, mods|m, key, + xproto.GrabModeAsync, xproto.GrabModeAsync).Check() + if err != nil { + return err + } + } + return nil +} + +// Ungrab undoes Grab. It will handle all combinations od modifiers found +// in xevent.IgnoreMods. +func Ungrab(xu *xgbutil.XUtil, win xproto.Window, + mods uint16, key xproto.Keycode) { + + for _, m := range xevent.IgnoreMods { + xproto.UngrabKeyChecked(xu.Conn(), key, win, mods|m).Check() + } +} + +// GrabKeyboard grabs the entire keyboard. +// Returns whether GrabStatus is successful and an error if one is reported by +// XGB. It is possible to not get an error and the grab to be unsuccessful. +// The purpose of 'win' is that after a grab is successful, ALL Key*Events will +// be sent to that window. Make sure you have a callback attached :-) +func GrabKeyboard(xu *xgbutil.XUtil, win xproto.Window) error { + reply, err := xproto.GrabKeyboard(xu.Conn(), false, win, 0, + xproto.GrabModeAsync, xproto.GrabModeAsync).Reply() + if err != nil { + return fmt.Errorf("GrabKeyboard: Error grabbing keyboard on "+ + "window '%x': %s", win, err) + } + + switch reply.Status { + case xproto.GrabStatusSuccess: + // all is well + case xproto.GrabStatusAlreadyGrabbed: + return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + + "Status: AlreadyGrabbed.") + case xproto.GrabStatusInvalidTime: + return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + + "Status: InvalidTime.") + case xproto.GrabStatusNotViewable: + return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + + "Status: NotViewable.") + case xproto.GrabStatusFrozen: + return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + + "Status: Frozen.") + } + return nil +} + +// UngrabKeyboard undoes GrabKeyboard. +func UngrabKeyboard(xu *xgbutil.XUtil) { + xproto.UngrabKeyboard(xu.Conn(), 0) +} + +// SmartGrab grabs the keyboard for the given window, and redirects all +// key events in the xevent main event loop to avoid races. +func SmartGrab(xu *xgbutil.XUtil, win xproto.Window) error { + err := GrabKeyboard(xu, win) + if err != nil { + return fmt.Errorf("SmartGrab: %s", err) + } + + // Now redirect all key events to the dummy window to prevent races + xevent.RedirectKeyEvents(xu, win) + + return nil +} + +// SmartUngrab reverses SmartGrab and stops redirecting all key events. +func SmartUngrab(xu *xgbutil.XUtil) { + UngrabKeyboard(xu) + + // Stop redirecting all key events + xevent.RedirectKeyEvents(xu, 0) +} + +// DummyGrab grabs the keyboard and sends all key events to the dummy window. +func DummyGrab(xu *xgbutil.XUtil) error { + return SmartGrab(xu, xu.Dummy()) +} + +// DummyUngrab ungrabs the keyboard from the dummy window. +func DummyUngrab(xu *xgbutil.XUtil) { + SmartUngrab(xu) +} diff --git a/vend/xgbutil/keybind/keysymdef.go b/vend/xgbutil/keybind/keysymdef.go new file mode 100644 index 0000000..f2f91e2 --- /dev/null +++ b/vend/xgbutil/keybind/keysymdef.go @@ -0,0 +1,2272 @@ +package keybind + +/* +This file contains the keysym definitions from X. +Taken from X11/keysymdef.h + +It also contains the "XFree86 vendor specific keysyms" taken from +X11/XF86keysym.h. + +We store this as a map because we need to be able to do reverse lookups. + +keysyms is a mapping from english strings to key symbols. +strKeysyms is a mapping from key symbols to english strings. +*/ + +import "github.com/jezek/xgb/xproto" + +func init() { + strKeysyms = make(map[xproto.Keysym]string, len(keysyms)) + for kstr, keysym := range keysyms { + // If we already have this keysym as a key, skip it. + // (Prefer the first. This may be bad.) + if _, ok := strKeysyms[keysym]; !ok { + strKeysyms[keysym] = kstr + } + } +} + +// weirdKeysyms is a feeble attempt to map english words to single +// characters. i.e., "bracketleft" -> [ and "exclam" to ! +var weirdKeysyms = map[string]rune{ + "space": ' ', + "exclam": '!', + "at": '@', + "numbersign": '#', + "dollar": '$', + "percent": '%', + "asciicircum": '^', + "ampersand": '&', + "asterisk": '*', + "parenleft": '(', + "parenright": ')', + "bracketleft": '[', + "bracketright": ']', + "braceleft": '{', + "braceright": '}', + "minus": '-', + "underscore": '_', + "equal": '=', + "plus": '+', + "backslash": '\\', + "bar": '|', + "semicolon": ';', + "colon": ':', + "apostrophe": '\'', + "quoteright": '\'', + "quotedbl": '"', + "less": '<', + "greater": '>', + "comma": ',', + "period": '.', + "slash": '/', + "question": '?', + "grave": '`', + "quoteleft": '`', + "asciitilde": '~', + "KP_Multiply": '*', + "KP_Divide": '/', + "KP_Subtract": '-', + "KP_Add": '+', + "KP_Decimal": '.', + "KP_0": '0', + "KP_1": '1', + "KP_2": '2', + "KP_3": '3', + "KP_4": '4', + "KP_5": '5', + "KP_6": '6', + "KP_7": '7', + "KP_8": '8', + "KP_9": '9', +} + +// strKeysyms is the reverse of keysyms. It is built upon initialization. +// TODO: Hard code the reverse map to be faster. +var strKeysyms map[xproto.Keysym]string + +var keysyms map[string]xproto.Keysym = map[string]xproto.Keysym{ + "VoidSymbol": 0xffffff, + "BackSpace": 0xff08, + "Tab": 0xff09, + "Linefeed": 0xff0a, + "Clear": 0xff0b, + "Return": 0xff0d, + "Pause": 0xff13, + "Scroll_Lock": 0xff14, + "Sys_Req": 0xff15, + "Escape": 0xff1b, + "Delete": 0xffff, + "Multi_key": 0xff20, + "Codeinput": 0xff37, + "SingleCandidate": 0xff3c, + "MultipleCandidate": 0xff3d, + "PreviousCandidate": 0xff3e, + "Kanji": 0xff21, + "Muhenkan": 0xff22, + "Henkan_Mode": 0xff23, + "Henkan": 0xff23, + "Romaji": 0xff24, + "Hiragana": 0xff25, + "Katakana": 0xff26, + "Hiragana_Katakana": 0xff27, + "Zenkaku": 0xff28, + "Hankaku": 0xff29, + "Zenkaku_Hankaku": 0xff2a, + "Touroku": 0xff2b, + "Massyo": 0xff2c, + "Kana_Lock": 0xff2d, + "Kana_Shift": 0xff2e, + "Eisu_Shift": 0xff2f, + "Eisu_toggle": 0xff30, + "Kanji_Bangou": 0xff37, + "Zen_Koho": 0xff3d, + "Mae_Koho": 0xff3e, + "Home": 0xff50, + "Left": 0xff51, + "Up": 0xff52, + "Right": 0xff53, + "Down": 0xff54, + "Prior": 0xff55, + "Page_Up": 0xff55, + "Next": 0xff56, + "Page_Down": 0xff56, + "End": 0xff57, + "Begin": 0xff58, + "Select": 0xff60, + "Print": 0xff61, + "Execute": 0xff62, + "Insert": 0xff63, + "Undo": 0xff65, + "Redo": 0xff66, + "Menu": 0xff67, + "Find": 0xff68, + "Cancel": 0xff69, + "Help": 0xff6a, + "Break": 0xff6b, + "Mode_switch": 0xff7e, + "script_switch": 0xff7e, + "Num_Lock": 0xff7f, + "KP_Space": 0xff80, + "KP_Tab": 0xff89, + "KP_Enter": 0xff8d, + "KP_F1": 0xff91, + "KP_F2": 0xff92, + "KP_F3": 0xff93, + "KP_F4": 0xff94, + "KP_Home": 0xff95, + "KP_Left": 0xff96, + "KP_Up": 0xff97, + "KP_Right": 0xff98, + "KP_Down": 0xff99, + "KP_Prior": 0xff9a, + "KP_Page_Up": 0xff9a, + "KP_Next": 0xff9b, + "KP_Page_Down": 0xff9b, + "KP_End": 0xff9c, + "KP_Begin": 0xff9d, + "KP_Insert": 0xff9e, + "KP_Delete": 0xff9f, + "KP_Equal": 0xffbd, + "KP_Multiply": 0xffaa, + "KP_Add": 0xffab, + "KP_Separator": 0xffac, + "KP_Subtract": 0xffad, + "KP_Decimal": 0xffae, + "KP_Divide": 0xffaf, + "KP_0": 0xffb0, + "KP_1": 0xffb1, + "KP_2": 0xffb2, + "KP_3": 0xffb3, + "KP_4": 0xffb4, + "KP_5": 0xffb5, + "KP_6": 0xffb6, + "KP_7": 0xffb7, + "KP_8": 0xffb8, + "KP_9": 0xffb9, + "F1": 0xffbe, + "F2": 0xffbf, + "F3": 0xffc0, + "F4": 0xffc1, + "F5": 0xffc2, + "F6": 0xffc3, + "F7": 0xffc4, + "F8": 0xffc5, + "F9": 0xffc6, + "F10": 0xffc7, + "F11": 0xffc8, + "L1": 0xffc8, + "F12": 0xffc9, + "L2": 0xffc9, + "F13": 0xffca, + "L3": 0xffca, + "F14": 0xffcb, + "L4": 0xffcb, + "F15": 0xffcc, + "L5": 0xffcc, + "F16": 0xffcd, + "L6": 0xffcd, + "F17": 0xffce, + "L7": 0xffce, + "F18": 0xffcf, + "L8": 0xffcf, + "F19": 0xffd0, + "L9": 0xffd0, + "F20": 0xffd1, + "L10": 0xffd1, + "F21": 0xffd2, + "R1": 0xffd2, + "F22": 0xffd3, + "R2": 0xffd3, + "F23": 0xffd4, + "R3": 0xffd4, + "F24": 0xffd5, + "R4": 0xffd5, + "F25": 0xffd6, + "R5": 0xffd6, + "F26": 0xffd7, + "R6": 0xffd7, + "F27": 0xffd8, + "R7": 0xffd8, + "F28": 0xffd9, + "R8": 0xffd9, + "F29": 0xffda, + "R9": 0xffda, + "F30": 0xffdb, + "R10": 0xffdb, + "F31": 0xffdc, + "R11": 0xffdc, + "F32": 0xffdd, + "R12": 0xffdd, + "F33": 0xffde, + "R13": 0xffde, + "F34": 0xffdf, + "R14": 0xffdf, + "F35": 0xffe0, + "R15": 0xffe0, + "Shift_L": 0xffe1, + "Shift_R": 0xffe2, + "Control_L": 0xffe3, + "Control_R": 0xffe4, + "Caps_Lock": 0xffe5, + "Shift_Lock": 0xffe6, + "Meta_L": 0xffe7, + "Meta_R": 0xffe8, + "Alt_L": 0xffe9, + "Alt_R": 0xffea, + "Super_L": 0xffeb, + "Super_R": 0xffec, + "Hyper_L": 0xffed, + "Hyper_R": 0xffee, + "ISO_Lock": 0xfe01, + "ISO_Level2_Latch": 0xfe02, + "ISO_Level3_Shift": 0xfe03, + "ISO_Level3_Latch": 0xfe04, + "ISO_Level3_Lock": 0xfe05, + "ISO_Level5_Shift": 0xfe11, + "ISO_Level5_Latch": 0xfe12, + "ISO_Level5_Lock": 0xfe13, + "ISO_Group_Shift": 0xff7e, + "ISO_Group_Latch": 0xfe06, + "ISO_Group_Lock": 0xfe07, + "ISO_Next_Group": 0xfe08, + "ISO_Next_Group_Lock": 0xfe09, + "ISO_Prev_Group": 0xfe0a, + "ISO_Prev_Group_Lock": 0xfe0b, + "ISO_First_Group": 0xfe0c, + "ISO_First_Group_Lock": 0xfe0d, + "ISO_Last_Group": 0xfe0e, + "ISO_Last_Group_Lock": 0xfe0f, + "ISO_Left_Tab": 0xfe20, + "ISO_Move_Line_Up": 0xfe21, + "ISO_Move_Line_Down": 0xfe22, + "ISO_Partial_Line_Up": 0xfe23, + "ISO_Partial_Line_Down": 0xfe24, + "ISO_Partial_Space_Left": 0xfe25, + "ISO_Partial_Space_Right": 0xfe26, + "ISO_Set_Margin_Left": 0xfe27, + "ISO_Set_Margin_Right": 0xfe28, + "ISO_Release_Margin_Left": 0xfe29, + "ISO_Release_Margin_Right": 0xfe2a, + "ISO_Release_Both_Margins": 0xfe2b, + "ISO_Fast_Cursor_Left": 0xfe2c, + "ISO_Fast_Cursor_Right": 0xfe2d, + "ISO_Fast_Cursor_Up": 0xfe2e, + "ISO_Fast_Cursor_Down": 0xfe2f, + "ISO_Continuous_Underline": 0xfe30, + "ISO_Discontinuous_Underline": 0xfe31, + "ISO_Emphasize": 0xfe32, + "ISO_Center_Object": 0xfe33, + "ISO_Enter": 0xfe34, + "dead_grave": 0xfe50, + "dead_acute": 0xfe51, + "dead_circumflex": 0xfe52, + "dead_tilde": 0xfe53, + "dead_perispomeni": 0xfe53, + "dead_macron": 0xfe54, + "dead_breve": 0xfe55, + "dead_abovedot": 0xfe56, + "dead_diaeresis": 0xfe57, + "dead_abovering": 0xfe58, + "dead_doubleacute": 0xfe59, + "dead_caron": 0xfe5a, + "dead_cedilla": 0xfe5b, + "dead_ogonek": 0xfe5c, + "dead_iota": 0xfe5d, + "dead_voiced_sound": 0xfe5e, + "dead_semivoiced_sound": 0xfe5f, + "dead_belowdot": 0xfe60, + "dead_hook": 0xfe61, + "dead_horn": 0xfe62, + "dead_stroke": 0xfe63, + "dead_abovecomma": 0xfe64, + "dead_psili": 0xfe64, + "dead_abovereversedcomma": 0xfe65, + "dead_dasia": 0xfe65, + "dead_doublegrave": 0xfe66, + "dead_belowring": 0xfe67, + "dead_belowmacron": 0xfe68, + "dead_belowcircumflex": 0xfe69, + "dead_belowtilde": 0xfe6a, + "dead_belowbreve": 0xfe6b, + "dead_belowdiaeresis": 0xfe6c, + "dead_invertedbreve": 0xfe6d, + "dead_belowcomma": 0xfe6e, + "dead_currency": 0xfe6f, + "dead_a": 0xfe80, + "dead_A": 0xfe81, + "dead_e": 0xfe82, + "dead_E": 0xfe83, + "dead_i": 0xfe84, + "dead_I": 0xfe85, + "dead_o": 0xfe86, + "dead_O": 0xfe87, + "dead_u": 0xfe88, + "dead_U": 0xfe89, + "dead_small_schwa": 0xfe8a, + "dead_capital_schwa": 0xfe8b, + "First_Virtual_Screen": 0xfed0, + "Prev_Virtual_Screen": 0xfed1, + "Next_Virtual_Screen": 0xfed2, + "Last_Virtual_Screen": 0xfed4, + "Terminate_Server": 0xfed5, + "AccessX_Enable": 0xfe70, + "AccessX_Feedback_Enable": 0xfe71, + "RepeatKeys_Enable": 0xfe72, + "SlowKeys_Enable": 0xfe73, + "BounceKeys_Enable": 0xfe74, + "StickyKeys_Enable": 0xfe75, + "MouseKeys_Enable": 0xfe76, + "MouseKeys_Accel_Enable": 0xfe77, + "Overlay1_Enable": 0xfe78, + "Overlay2_Enable": 0xfe79, + "AudibleBell_Enable": 0xfe7a, + "Pointer_Left": 0xfee0, + "Pointer_Right": 0xfee1, + "Pointer_Up": 0xfee2, + "Pointer_Down": 0xfee3, + "Pointer_UpLeft": 0xfee4, + "Pointer_UpRight": 0xfee5, + "Pointer_DownLeft": 0xfee6, + "Pointer_DownRight": 0xfee7, + "Pointer_Button_Dflt": 0xfee8, + "Pointer_Button1": 0xfee9, + "Pointer_Button2": 0xfeea, + "Pointer_Button3": 0xfeeb, + "Pointer_Button4": 0xfeec, + "Pointer_Button5": 0xfeed, + "Pointer_DblClick_Dflt": 0xfeee, + "Pointer_DblClick1": 0xfeef, + "Pointer_DblClick2": 0xfef0, + "Pointer_DblClick3": 0xfef1, + "Pointer_DblClick4": 0xfef2, + "Pointer_DblClick5": 0xfef3, + "Pointer_Drag_Dflt": 0xfef4, + "Pointer_Drag1": 0xfef5, + "Pointer_Drag2": 0xfef6, + "Pointer_Drag3": 0xfef7, + "Pointer_Drag4": 0xfef8, + "Pointer_Drag5": 0xfefd, + "Pointer_EnableKeys": 0xfef9, + "Pointer_Accelerate": 0xfefa, + "Pointer_DfltBtnNext": 0xfefb, + "Pointer_DfltBtnPrev": 0xfefc, + "3270_Duplicate": 0xfd01, + "3270_FieldMark": 0xfd02, + "3270_Right2": 0xfd03, + "3270_Left2": 0xfd04, + "3270_BackTab": 0xfd05, + "3270_EraseEOF": 0xfd06, + "3270_EraseInput": 0xfd07, + "3270_Reset": 0xfd08, + "3270_Quit": 0xfd09, + "3270_PA1": 0xfd0a, + "3270_PA2": 0xfd0b, + "3270_PA3": 0xfd0c, + "3270_Test": 0xfd0d, + "3270_Attn": 0xfd0e, + "3270_CursorBlink": 0xfd0f, + "3270_AltCursor": 0xfd10, + "3270_KeyClick": 0xfd11, + "3270_Jump": 0xfd12, + "3270_Ident": 0xfd13, + "3270_Rule": 0xfd14, + "3270_Copy": 0xfd15, + "3270_Play": 0xfd16, + "3270_Setup": 0xfd17, + "3270_Record": 0xfd18, + "3270_ChangeScreen": 0xfd19, + "3270_DeleteWord": 0xfd1a, + "3270_ExSelect": 0xfd1b, + "3270_CursorSelect": 0xfd1c, + "3270_PrintScreen": 0xfd1d, + "3270_Enter": 0xfd1e, + "space": 0x0020, + "exclam": 0x0021, + "quotedbl": 0x0022, + "numbersign": 0x0023, + "dollar": 0x0024, + "percent": 0x0025, + "ampersand": 0x0026, + "apostrophe": 0x0027, + "quoteright": 0x0027, + "parenleft": 0x0028, + "parenright": 0x0029, + "asterisk": 0x002a, + "plus": 0x002b, + "comma": 0x002c, + "minus": 0x002d, + "period": 0x002e, + "slash": 0x002f, + "0": 0x0030, + "1": 0x0031, + "2": 0x0032, + "3": 0x0033, + "4": 0x0034, + "5": 0x0035, + "6": 0x0036, + "7": 0x0037, + "8": 0x0038, + "9": 0x0039, + "colon": 0x003a, + "semicolon": 0x003b, + "less": 0x003c, + "equal": 0x003d, + "greater": 0x003e, + "question": 0x003f, + "at": 0x0040, + "A": 0x0041, + "B": 0x0042, + "C": 0x0043, + "D": 0x0044, + "E": 0x0045, + "F": 0x0046, + "G": 0x0047, + "H": 0x0048, + "I": 0x0049, + "J": 0x004a, + "K": 0x004b, + "L": 0x004c, + "M": 0x004d, + "N": 0x004e, + "O": 0x004f, + "P": 0x0050, + "Q": 0x0051, + "R": 0x0052, + "S": 0x0053, + "T": 0x0054, + "U": 0x0055, + "V": 0x0056, + "W": 0x0057, + "X": 0x0058, + "Y": 0x0059, + "Z": 0x005a, + "bracketleft": 0x005b, + "backslash": 0x005c, + "bracketright": 0x005d, + "asciicircum": 0x005e, + "underscore": 0x005f, + "grave": 0x0060, + "quoteleft": 0x0060, + "a": 0x0061, + "b": 0x0062, + "c": 0x0063, + "d": 0x0064, + "e": 0x0065, + "f": 0x0066, + "g": 0x0067, + "h": 0x0068, + "i": 0x0069, + "j": 0x006a, + "k": 0x006b, + "l": 0x006c, + "m": 0x006d, + "n": 0x006e, + "o": 0x006f, + "p": 0x0070, + "q": 0x0071, + "r": 0x0072, + "s": 0x0073, + "t": 0x0074, + "u": 0x0075, + "v": 0x0076, + "w": 0x0077, + "x": 0x0078, + "y": 0x0079, + "z": 0x007a, + "braceleft": 0x007b, + "bar": 0x007c, + "braceright": 0x007d, + "asciitilde": 0x007e, + "nobreakspace": 0x00a0, + "exclamdown": 0x00a1, + "cent": 0x00a2, + "sterling": 0x00a3, + "currency": 0x00a4, + "yen": 0x00a5, + "brokenbar": 0x00a6, + "section": 0x00a7, + "diaeresis": 0x00a8, + "copyright": 0x00a9, + "ordfeminine": 0x00aa, + "guillemotleft": 0x00ab, + "notsign": 0x00ac, + "hyphen": 0x00ad, + "registered": 0x00ae, + "macron": 0x00af, + "degree": 0x00b0, + "plusminus": 0x00b1, + "twosuperior": 0x00b2, + "threesuperior": 0x00b3, + "acute": 0x00b4, + "mu": 0x00b5, + "paragraph": 0x00b6, + "periodcentered": 0x00b7, + "cedilla": 0x00b8, + "onesuperior": 0x00b9, + "masculine": 0x00ba, + "guillemotright": 0x00bb, + "onequarter": 0x00bc, + "onehalf": 0x00bd, + "threequarters": 0x00be, + "questiondown": 0x00bf, + "Agrave": 0x00c0, + "Aacute": 0x00c1, + "Acircumflex": 0x00c2, + "Atilde": 0x00c3, + "Adiaeresis": 0x00c4, + "Aring": 0x00c5, + "AE": 0x00c6, + "Ccedilla": 0x00c7, + "Egrave": 0x00c8, + "Eacute": 0x00c9, + "Ecircumflex": 0x00ca, + "Ediaeresis": 0x00cb, + "Igrave": 0x00cc, + "Iacute": 0x00cd, + "Icircumflex": 0x00ce, + "Idiaeresis": 0x00cf, + "ETH": 0x00d0, + "Eth": 0x00d0, + "Ntilde": 0x00d1, + "Ograve": 0x00d2, + "Oacute": 0x00d3, + "Ocircumflex": 0x00d4, + "Otilde": 0x00d5, + "Odiaeresis": 0x00d6, + "multiply": 0x00d7, + "Oslash": 0x00d8, + "Ooblique": 0x00d8, + "Ugrave": 0x00d9, + "Uacute": 0x00da, + "Ucircumflex": 0x00db, + "Udiaeresis": 0x00dc, + "Yacute": 0x00dd, + "THORN": 0x00de, + "Thorn": 0x00de, + "ssharp": 0x00df, + "agrave": 0x00e0, + "aacute": 0x00e1, + "acircumflex": 0x00e2, + "atilde": 0x00e3, + "adiaeresis": 0x00e4, + "aring": 0x00e5, + "ae": 0x00e6, + "ccedilla": 0x00e7, + "egrave": 0x00e8, + "eacute": 0x00e9, + "ecircumflex": 0x00ea, + "ediaeresis": 0x00eb, + "igrave": 0x00ec, + "iacute": 0x00ed, + "icircumflex": 0x00ee, + "idiaeresis": 0x00ef, + "eth": 0x00f0, + "ntilde": 0x00f1, + "ograve": 0x00f2, + "oacute": 0x00f3, + "ocircumflex": 0x00f4, + "otilde": 0x00f5, + "odiaeresis": 0x00f6, + "division": 0x00f7, + "oslash": 0x00f8, + "ooblique": 0x00f8, + "ugrave": 0x00f9, + "uacute": 0x00fa, + "ucircumflex": 0x00fb, + "udiaeresis": 0x00fc, + "yacute": 0x00fd, + "thorn": 0x00fe, + "ydiaeresis": 0x00ff, + "Aogonek": 0x01a1, + "breve": 0x01a2, + "Lstroke": 0x01a3, + "Lcaron": 0x01a5, + "Sacute": 0x01a6, + "Scaron": 0x01a9, + "Scedilla": 0x01aa, + "Tcaron": 0x01ab, + "Zacute": 0x01ac, + "Zcaron": 0x01ae, + "Zabovedot": 0x01af, + "aogonek": 0x01b1, + "ogonek": 0x01b2, + "lstroke": 0x01b3, + "lcaron": 0x01b5, + "sacute": 0x01b6, + "caron": 0x01b7, + "scaron": 0x01b9, + "scedilla": 0x01ba, + "tcaron": 0x01bb, + "zacute": 0x01bc, + "doubleacute": 0x01bd, + "zcaron": 0x01be, + "zabovedot": 0x01bf, + "Racute": 0x01c0, + "Abreve": 0x01c3, + "Lacute": 0x01c5, + "Cacute": 0x01c6, + "Ccaron": 0x01c8, + "Eogonek": 0x01ca, + "Ecaron": 0x01cc, + "Dcaron": 0x01cf, + "Dstroke": 0x01d0, + "Nacute": 0x01d1, + "Ncaron": 0x01d2, + "Odoubleacute": 0x01d5, + "Rcaron": 0x01d8, + "Uring": 0x01d9, + "Udoubleacute": 0x01db, + "Tcedilla": 0x01de, + "racute": 0x01e0, + "abreve": 0x01e3, + "lacute": 0x01e5, + "cacute": 0x01e6, + "ccaron": 0x01e8, + "eogonek": 0x01ea, + "ecaron": 0x01ec, + "dcaron": 0x01ef, + "dstroke": 0x01f0, + "nacute": 0x01f1, + "ncaron": 0x01f2, + "odoubleacute": 0x01f5, + "udoubleacute": 0x01fb, + "rcaron": 0x01f8, + "uring": 0x01f9, + "tcedilla": 0x01fe, + "abovedot": 0x01ff, + "Hstroke": 0x02a1, + "Hcircumflex": 0x02a6, + "Iabovedot": 0x02a9, + "Gbreve": 0x02ab, + "Jcircumflex": 0x02ac, + "hstroke": 0x02b1, + "hcircumflex": 0x02b6, + "idotless": 0x02b9, + "gbreve": 0x02bb, + "jcircumflex": 0x02bc, + "Cabovedot": 0x02c5, + "Ccircumflex": 0x02c6, + "Gabovedot": 0x02d5, + "Gcircumflex": 0x02d8, + "Ubreve": 0x02dd, + "Scircumflex": 0x02de, + "cabovedot": 0x02e5, + "ccircumflex": 0x02e6, + "gabovedot": 0x02f5, + "gcircumflex": 0x02f8, + "ubreve": 0x02fd, + "scircumflex": 0x02fe, + "kra": 0x03a2, + "kappa": 0x03a2, + "Rcedilla": 0x03a3, + "Itilde": 0x03a5, + "Lcedilla": 0x03a6, + "Emacron": 0x03aa, + "Gcedilla": 0x03ab, + "Tslash": 0x03ac, + "rcedilla": 0x03b3, + "itilde": 0x03b5, + "lcedilla": 0x03b6, + "emacron": 0x03ba, + "gcedilla": 0x03bb, + "tslash": 0x03bc, + "ENG": 0x03bd, + "eng": 0x03bf, + "Amacron": 0x03c0, + "Iogonek": 0x03c7, + "Eabovedot": 0x03cc, + "Imacron": 0x03cf, + "Ncedilla": 0x03d1, + "Omacron": 0x03d2, + "Kcedilla": 0x03d3, + "Uogonek": 0x03d9, + "Utilde": 0x03dd, + "Umacron": 0x03de, + "amacron": 0x03e0, + "iogonek": 0x03e7, + "eabovedot": 0x03ec, + "imacron": 0x03ef, + "ncedilla": 0x03f1, + "omacron": 0x03f2, + "kcedilla": 0x03f3, + "uogonek": 0x03f9, + "utilde": 0x03fd, + "umacron": 0x03fe, + "Babovedot": 0x1001e02, + "babovedot": 0x1001e03, + "Dabovedot": 0x1001e0a, + "Wgrave": 0x1001e80, + "Wacute": 0x1001e82, + "dabovedot": 0x1001e0b, + "Ygrave": 0x1001ef2, + "Fabovedot": 0x1001e1e, + "fabovedot": 0x1001e1f, + "Mabovedot": 0x1001e40, + "mabovedot": 0x1001e41, + "Pabovedot": 0x1001e56, + "wgrave": 0x1001e81, + "pabovedot": 0x1001e57, + "wacute": 0x1001e83, + "Sabovedot": 0x1001e60, + "ygrave": 0x1001ef3, + "Wdiaeresis": 0x1001e84, + "wdiaeresis": 0x1001e85, + "sabovedot": 0x1001e61, + "Wcircumflex": 0x1000174, + "Tabovedot": 0x1001e6a, + "Ycircumflex": 0x1000176, + "wcircumflex": 0x1000175, + "tabovedot": 0x1001e6b, + "ycircumflex": 0x1000177, + "OE": 0x13bc, + "oe": 0x13bd, + "Ydiaeresis": 0x13be, + "overline": 0x047e, + "kana_fullstop": 0x04a1, + "kana_openingbracket": 0x04a2, + "kana_closingbracket": 0x04a3, + "kana_comma": 0x04a4, + "kana_conjunctive": 0x04a5, + "kana_middledot": 0x04a5, + "kana_WO": 0x04a6, + "kana_a": 0x04a7, + "kana_i": 0x04a8, + "kana_u": 0x04a9, + "kana_e": 0x04aa, + "kana_o": 0x04ab, + "kana_ya": 0x04ac, + "kana_yu": 0x04ad, + "kana_yo": 0x04ae, + "kana_tsu": 0x04af, + "kana_tu": 0x04af, + "prolongedsound": 0x04b0, + "kana_A": 0x04b1, + "kana_I": 0x04b2, + "kana_U": 0x04b3, + "kana_E": 0x04b4, + "kana_O": 0x04b5, + "kana_KA": 0x04b6, + "kana_KI": 0x04b7, + "kana_KU": 0x04b8, + "kana_KE": 0x04b9, + "kana_KO": 0x04ba, + "kana_SA": 0x04bb, + "kana_SHI": 0x04bc, + "kana_SU": 0x04bd, + "kana_SE": 0x04be, + "kana_SO": 0x04bf, + "kana_TA": 0x04c0, + "kana_CHI": 0x04c1, + "kana_TI": 0x04c1, + "kana_TSU": 0x04c2, + "kana_TU": 0x04c2, + "kana_TE": 0x04c3, + "kana_TO": 0x04c4, + "kana_NA": 0x04c5, + "kana_NI": 0x04c6, + "kana_NU": 0x04c7, + "kana_NE": 0x04c8, + "kana_NO": 0x04c9, + "kana_HA": 0x04ca, + "kana_HI": 0x04cb, + "kana_FU": 0x04cc, + "kana_HU": 0x04cc, + "kana_HE": 0x04cd, + "kana_HO": 0x04ce, + "kana_MA": 0x04cf, + "kana_MI": 0x04d0, + "kana_MU": 0x04d1, + "kana_ME": 0x04d2, + "kana_MO": 0x04d3, + "kana_YA": 0x04d4, + "kana_YU": 0x04d5, + "kana_YO": 0x04d6, + "kana_RA": 0x04d7, + "kana_RI": 0x04d8, + "kana_RU": 0x04d9, + "kana_RE": 0x04da, + "kana_RO": 0x04db, + "kana_WA": 0x04dc, + "kana_N": 0x04dd, + "voicedsound": 0x04de, + "semivoicedsound": 0x04df, + "kana_switch": 0xff7e, + "Farsi_0": 0x10006f0, + "Farsi_1": 0x10006f1, + "Farsi_2": 0x10006f2, + "Farsi_3": 0x10006f3, + "Farsi_4": 0x10006f4, + "Farsi_5": 0x10006f5, + "Farsi_6": 0x10006f6, + "Farsi_7": 0x10006f7, + "Farsi_8": 0x10006f8, + "Farsi_9": 0x10006f9, + "Arabic_percent": 0x100066a, + "Arabic_superscript_alef": 0x1000670, + "Arabic_tteh": 0x1000679, + "Arabic_peh": 0x100067e, + "Arabic_tcheh": 0x1000686, + "Arabic_ddal": 0x1000688, + "Arabic_rreh": 0x1000691, + "Arabic_comma": 0x05ac, + "Arabic_fullstop": 0x10006d4, + "Arabic_0": 0x1000660, + "Arabic_1": 0x1000661, + "Arabic_2": 0x1000662, + "Arabic_3": 0x1000663, + "Arabic_4": 0x1000664, + "Arabic_5": 0x1000665, + "Arabic_6": 0x1000666, + "Arabic_7": 0x1000667, + "Arabic_8": 0x1000668, + "Arabic_9": 0x1000669, + "Arabic_semicolon": 0x05bb, + "Arabic_question_mark": 0x05bf, + "Arabic_hamza": 0x05c1, + "Arabic_maddaonalef": 0x05c2, + "Arabic_hamzaonalef": 0x05c3, + "Arabic_hamzaonwaw": 0x05c4, + "Arabic_hamzaunderalef": 0x05c5, + "Arabic_hamzaonyeh": 0x05c6, + "Arabic_alef": 0x05c7, + "Arabic_beh": 0x05c8, + "Arabic_tehmarbuta": 0x05c9, + "Arabic_teh": 0x05ca, + "Arabic_theh": 0x05cb, + "Arabic_jeem": 0x05cc, + "Arabic_hah": 0x05cd, + "Arabic_khah": 0x05ce, + "Arabic_dal": 0x05cf, + "Arabic_thal": 0x05d0, + "Arabic_ra": 0x05d1, + "Arabic_zain": 0x05d2, + "Arabic_seen": 0x05d3, + "Arabic_sheen": 0x05d4, + "Arabic_sad": 0x05d5, + "Arabic_dad": 0x05d6, + "Arabic_tah": 0x05d7, + "Arabic_zah": 0x05d8, + "Arabic_ain": 0x05d9, + "Arabic_ghain": 0x05da, + "Arabic_tatweel": 0x05e0, + "Arabic_feh": 0x05e1, + "Arabic_qaf": 0x05e2, + "Arabic_kaf": 0x05e3, + "Arabic_lam": 0x05e4, + "Arabic_meem": 0x05e5, + "Arabic_noon": 0x05e6, + "Arabic_ha": 0x05e7, + "Arabic_heh": 0x05e7, + "Arabic_waw": 0x05e8, + "Arabic_alefmaksura": 0x05e9, + "Arabic_yeh": 0x05ea, + "Arabic_fathatan": 0x05eb, + "Arabic_dammatan": 0x05ec, + "Arabic_kasratan": 0x05ed, + "Arabic_fatha": 0x05ee, + "Arabic_damma": 0x05ef, + "Arabic_kasra": 0x05f0, + "Arabic_shadda": 0x05f1, + "Arabic_sukun": 0x05f2, + "Arabic_madda_above": 0x1000653, + "Arabic_hamza_above": 0x1000654, + "Arabic_hamza_below": 0x1000655, + "Arabic_jeh": 0x1000698, + "Arabic_veh": 0x10006a4, + "Arabic_keheh": 0x10006a9, + "Arabic_gaf": 0x10006af, + "Arabic_noon_ghunna": 0x10006ba, + "Arabic_heh_doachashmee": 0x10006be, + "Farsi_yeh": 0x10006cc, + "Arabic_farsi_yeh": 0x10006cc, + "Arabic_yeh_baree": 0x10006d2, + "Arabic_heh_goal": 0x10006c1, + "Arabic_switch": 0xff7e, + "Cyrillic_GHE_bar": 0x1000492, + "Cyrillic_ghe_bar": 0x1000493, + "Cyrillic_ZHE_descender": 0x1000496, + "Cyrillic_zhe_descender": 0x1000497, + "Cyrillic_KA_descender": 0x100049a, + "Cyrillic_ka_descender": 0x100049b, + "Cyrillic_KA_vertstroke": 0x100049c, + "Cyrillic_ka_vertstroke": 0x100049d, + "Cyrillic_EN_descender": 0x10004a2, + "Cyrillic_en_descender": 0x10004a3, + "Cyrillic_U_straight": 0x10004ae, + "Cyrillic_u_straight": 0x10004af, + "Cyrillic_U_straight_bar": 0x10004b0, + "Cyrillic_u_straight_bar": 0x10004b1, + "Cyrillic_HA_descender": 0x10004b2, + "Cyrillic_ha_descender": 0x10004b3, + "Cyrillic_CHE_descender": 0x10004b6, + "Cyrillic_che_descender": 0x10004b7, + "Cyrillic_CHE_vertstroke": 0x10004b8, + "Cyrillic_che_vertstroke": 0x10004b9, + "Cyrillic_SHHA": 0x10004ba, + "Cyrillic_shha": 0x10004bb, + "Cyrillic_SCHWA": 0x10004d8, + "Cyrillic_schwa": 0x10004d9, + "Cyrillic_I_macron": 0x10004e2, + "Cyrillic_i_macron": 0x10004e3, + "Cyrillic_O_bar": 0x10004e8, + "Cyrillic_o_bar": 0x10004e9, + "Cyrillic_U_macron": 0x10004ee, + "Cyrillic_u_macron": 0x10004ef, + "Serbian_dje": 0x06a1, + "Macedonia_gje": 0x06a2, + "Cyrillic_io": 0x06a3, + "Ukrainian_ie": 0x06a4, + "Ukranian_je": 0x06a4, + "Macedonia_dse": 0x06a5, + "Ukrainian_i": 0x06a6, + "Ukranian_i": 0x06a6, + "Ukrainian_yi": 0x06a7, + "Ukranian_yi": 0x06a7, + "Cyrillic_je": 0x06a8, + "Serbian_je": 0x06a8, + "Cyrillic_lje": 0x06a9, + "Serbian_lje": 0x06a9, + "Cyrillic_nje": 0x06aa, + "Serbian_nje": 0x06aa, + "Serbian_tshe": 0x06ab, + "Macedonia_kje": 0x06ac, + "Ukrainian_ghe_with_upturn": 0x06ad, + "Byelorussian_shortu": 0x06ae, + "Cyrillic_dzhe": 0x06af, + "Serbian_dze": 0x06af, + "numerosign": 0x06b0, + "Serbian_DJE": 0x06b1, + "Macedonia_GJE": 0x06b2, + "Cyrillic_IO": 0x06b3, + "Ukrainian_IE": 0x06b4, + "Ukranian_JE": 0x06b4, + "Macedonia_DSE": 0x06b5, + "Ukrainian_I": 0x06b6, + "Ukranian_I": 0x06b6, + "Ukrainian_YI": 0x06b7, + "Ukranian_YI": 0x06b7, + "Cyrillic_JE": 0x06b8, + "Serbian_JE": 0x06b8, + "Cyrillic_LJE": 0x06b9, + "Serbian_LJE": 0x06b9, + "Cyrillic_NJE": 0x06ba, + "Serbian_NJE": 0x06ba, + "Serbian_TSHE": 0x06bb, + "Macedonia_KJE": 0x06bc, + "Ukrainian_GHE_WITH_UPTURN": 0x06bd, + "Byelorussian_SHORTU": 0x06be, + "Cyrillic_DZHE": 0x06bf, + "Serbian_DZE": 0x06bf, + "Cyrillic_yu": 0x06c0, + "Cyrillic_a": 0x06c1, + "Cyrillic_be": 0x06c2, + "Cyrillic_tse": 0x06c3, + "Cyrillic_de": 0x06c4, + "Cyrillic_ie": 0x06c5, + "Cyrillic_ef": 0x06c6, + "Cyrillic_ghe": 0x06c7, + "Cyrillic_ha": 0x06c8, + "Cyrillic_i": 0x06c9, + "Cyrillic_shorti": 0x06ca, + "Cyrillic_ka": 0x06cb, + "Cyrillic_el": 0x06cc, + "Cyrillic_em": 0x06cd, + "Cyrillic_en": 0x06ce, + "Cyrillic_o": 0x06cf, + "Cyrillic_pe": 0x06d0, + "Cyrillic_ya": 0x06d1, + "Cyrillic_er": 0x06d2, + "Cyrillic_es": 0x06d3, + "Cyrillic_te": 0x06d4, + "Cyrillic_u": 0x06d5, + "Cyrillic_zhe": 0x06d6, + "Cyrillic_ve": 0x06d7, + "Cyrillic_softsign": 0x06d8, + "Cyrillic_yeru": 0x06d9, + "Cyrillic_ze": 0x06da, + "Cyrillic_sha": 0x06db, + "Cyrillic_e": 0x06dc, + "Cyrillic_shcha": 0x06dd, + "Cyrillic_che": 0x06de, + "Cyrillic_hardsign": 0x06df, + "Cyrillic_YU": 0x06e0, + "Cyrillic_A": 0x06e1, + "Cyrillic_BE": 0x06e2, + "Cyrillic_TSE": 0x06e3, + "Cyrillic_DE": 0x06e4, + "Cyrillic_IE": 0x06e5, + "Cyrillic_EF": 0x06e6, + "Cyrillic_GHE": 0x06e7, + "Cyrillic_HA": 0x06e8, + "Cyrillic_I": 0x06e9, + "Cyrillic_SHORTI": 0x06ea, + "Cyrillic_KA": 0x06eb, + "Cyrillic_EL": 0x06ec, + "Cyrillic_EM": 0x06ed, + "Cyrillic_EN": 0x06ee, + "Cyrillic_O": 0x06ef, + "Cyrillic_PE": 0x06f0, + "Cyrillic_YA": 0x06f1, + "Cyrillic_ER": 0x06f2, + "Cyrillic_ES": 0x06f3, + "Cyrillic_TE": 0x06f4, + "Cyrillic_U": 0x06f5, + "Cyrillic_ZHE": 0x06f6, + "Cyrillic_VE": 0x06f7, + "Cyrillic_SOFTSIGN": 0x06f8, + "Cyrillic_YERU": 0x06f9, + "Cyrillic_ZE": 0x06fa, + "Cyrillic_SHA": 0x06fb, + "Cyrillic_E": 0x06fc, + "Cyrillic_SHCHA": 0x06fd, + "Cyrillic_CHE": 0x06fe, + "Cyrillic_HARDSIGN": 0x06ff, + "Greek_ALPHAaccent": 0x07a1, + "Greek_EPSILONaccent": 0x07a2, + "Greek_ETAaccent": 0x07a3, + "Greek_IOTAaccent": 0x07a4, + "Greek_IOTAdieresis": 0x07a5, + "Greek_IOTAdiaeresis": 0x07a5, + "Greek_OMICRONaccent": 0x07a7, + "Greek_UPSILONaccent": 0x07a8, + "Greek_UPSILONdieresis": 0x07a9, + "Greek_OMEGAaccent": 0x07ab, + "Greek_accentdieresis": 0x07ae, + "Greek_horizbar": 0x07af, + "Greek_alphaaccent": 0x07b1, + "Greek_epsilonaccent": 0x07b2, + "Greek_etaaccent": 0x07b3, + "Greek_iotaaccent": 0x07b4, + "Greek_iotadieresis": 0x07b5, + "Greek_iotaaccentdieresis": 0x07b6, + "Greek_omicronaccent": 0x07b7, + "Greek_upsilonaccent": 0x07b8, + "Greek_upsilondieresis": 0x07b9, + "Greek_upsilonaccentdieresis": 0x07ba, + "Greek_omegaaccent": 0x07bb, + "Greek_ALPHA": 0x07c1, + "Greek_BETA": 0x07c2, + "Greek_GAMMA": 0x07c3, + "Greek_DELTA": 0x07c4, + "Greek_EPSILON": 0x07c5, + "Greek_ZETA": 0x07c6, + "Greek_ETA": 0x07c7, + "Greek_THETA": 0x07c8, + "Greek_IOTA": 0x07c9, + "Greek_KAPPA": 0x07ca, + "Greek_LAMDA": 0x07cb, + "Greek_LAMBDA": 0x07cb, + "Greek_MU": 0x07cc, + "Greek_NU": 0x07cd, + "Greek_XI": 0x07ce, + "Greek_OMICRON": 0x07cf, + "Greek_PI": 0x07d0, + "Greek_RHO": 0x07d1, + "Greek_SIGMA": 0x07d2, + "Greek_TAU": 0x07d4, + "Greek_UPSILON": 0x07d5, + "Greek_PHI": 0x07d6, + "Greek_CHI": 0x07d7, + "Greek_PSI": 0x07d8, + "Greek_OMEGA": 0x07d9, + "Greek_alpha": 0x07e1, + "Greek_beta": 0x07e2, + "Greek_gamma": 0x07e3, + "Greek_delta": 0x07e4, + "Greek_epsilon": 0x07e5, + "Greek_zeta": 0x07e6, + "Greek_eta": 0x07e7, + "Greek_theta": 0x07e8, + "Greek_iota": 0x07e9, + "Greek_kappa": 0x07ea, + "Greek_lamda": 0x07eb, + "Greek_lambda": 0x07eb, + "Greek_mu": 0x07ec, + "Greek_nu": 0x07ed, + "Greek_xi": 0x07ee, + "Greek_omicron": 0x07ef, + "Greek_pi": 0x07f0, + "Greek_rho": 0x07f1, + "Greek_sigma": 0x07f2, + "Greek_finalsmallsigma": 0x07f3, + "Greek_tau": 0x07f4, + "Greek_upsilon": 0x07f5, + "Greek_phi": 0x07f6, + "Greek_chi": 0x07f7, + "Greek_psi": 0x07f8, + "Greek_omega": 0x07f9, + "Greek_switch": 0xff7e, + "leftradical": 0x08a1, + "topleftradical": 0x08a2, + "horizconnector": 0x08a3, + "topintegral": 0x08a4, + "botintegral": 0x08a5, + "vertconnector": 0x08a6, + "topleftsqbracket": 0x08a7, + "botleftsqbracket": 0x08a8, + "toprightsqbracket": 0x08a9, + "botrightsqbracket": 0x08aa, + "topleftparens": 0x08ab, + "botleftparens": 0x08ac, + "toprightparens": 0x08ad, + "botrightparens": 0x08ae, + "leftmiddlecurlybrace": 0x08af, + "rightmiddlecurlybrace": 0x08b0, + "topleftsummation": 0x08b1, + "botleftsummation": 0x08b2, + "topvertsummationconnector": 0x08b3, + "botvertsummationconnector": 0x08b4, + "toprightsummation": 0x08b5, + "botrightsummation": 0x08b6, + "rightmiddlesummation": 0x08b7, + "lessthanequal": 0x08bc, + "notequal": 0x08bd, + "greaterthanequal": 0x08be, + "integral": 0x08bf, + "therefore": 0x08c0, + "variation": 0x08c1, + "infinity": 0x08c2, + "nabla": 0x08c5, + "approximate": 0x08c8, + "similarequal": 0x08c9, + "ifonlyif": 0x08cd, + "implies": 0x08ce, + "identical": 0x08cf, + "radical": 0x08d6, + "includedin": 0x08da, + "includes": 0x08db, + "intersection": 0x08dc, + "union": 0x08dd, + "logicaland": 0x08de, + "logicalor": 0x08df, + "partialderivative": 0x08ef, + "function": 0x08f6, + "leftarrow": 0x08fb, + "uparrow": 0x08fc, + "rightarrow": 0x08fd, + "downarrow": 0x08fe, + "blank": 0x09df, + "soliddiamond": 0x09e0, + "checkerboard": 0x09e1, + "ht": 0x09e2, + "ff": 0x09e3, + "cr": 0x09e4, + "lf": 0x09e5, + "nl": 0x09e8, + "vt": 0x09e9, + "lowrightcorner": 0x09ea, + "uprightcorner": 0x09eb, + "upleftcorner": 0x09ec, + "lowleftcorner": 0x09ed, + "crossinglines": 0x09ee, + "horizlinescan1": 0x09ef, + "horizlinescan3": 0x09f0, + "horizlinescan5": 0x09f1, + "horizlinescan7": 0x09f2, + "horizlinescan9": 0x09f3, + "leftt": 0x09f4, + "rightt": 0x09f5, + "bott": 0x09f6, + "topt": 0x09f7, + "vertbar": 0x09f8, + "emspace": 0x0aa1, + "enspace": 0x0aa2, + "em3space": 0x0aa3, + "em4space": 0x0aa4, + "digitspace": 0x0aa5, + "punctspace": 0x0aa6, + "thinspace": 0x0aa7, + "hairspace": 0x0aa8, + "emdash": 0x0aa9, + "endash": 0x0aaa, + "signifblank": 0x0aac, + "ellipsis": 0x0aae, + "doubbaselinedot": 0x0aaf, + "onethird": 0x0ab0, + "twothirds": 0x0ab1, + "onefifth": 0x0ab2, + "twofifths": 0x0ab3, + "threefifths": 0x0ab4, + "fourfifths": 0x0ab5, + "onesixth": 0x0ab6, + "fivesixths": 0x0ab7, + "careof": 0x0ab8, + "figdash": 0x0abb, + "leftanglebracket": 0x0abc, + "decimalpoint": 0x0abd, + "rightanglebracket": 0x0abe, + "marker": 0x0abf, + "oneeighth": 0x0ac3, + "threeeighths": 0x0ac4, + "fiveeighths": 0x0ac5, + "seveneighths": 0x0ac6, + "trademark": 0x0ac9, + "signaturemark": 0x0aca, + "trademarkincircle": 0x0acb, + "leftopentriangle": 0x0acc, + "rightopentriangle": 0x0acd, + "emopencircle": 0x0ace, + "emopenrectangle": 0x0acf, + "leftsinglequotemark": 0x0ad0, + "rightsinglequotemark": 0x0ad1, + "leftdoublequotemark": 0x0ad2, + "rightdoublequotemark": 0x0ad3, + "prescription": 0x0ad4, + "minutes": 0x0ad6, + "seconds": 0x0ad7, + "latincross": 0x0ad9, + "hexagram": 0x0ada, + "filledrectbullet": 0x0adb, + "filledlefttribullet": 0x0adc, + "filledrighttribullet": 0x0add, + "emfilledcircle": 0x0ade, + "emfilledrect": 0x0adf, + "enopencircbullet": 0x0ae0, + "enopensquarebullet": 0x0ae1, + "openrectbullet": 0x0ae2, + "opentribulletup": 0x0ae3, + "opentribulletdown": 0x0ae4, + "openstar": 0x0ae5, + "enfilledcircbullet": 0x0ae6, + "enfilledsqbullet": 0x0ae7, + "filledtribulletup": 0x0ae8, + "filledtribulletdown": 0x0ae9, + "leftpointer": 0x0aea, + "rightpointer": 0x0aeb, + "club": 0x0aec, + "diamond": 0x0aed, + "heart": 0x0aee, + "maltesecross": 0x0af0, + "dagger": 0x0af1, + "doubledagger": 0x0af2, + "checkmark": 0x0af3, + "ballotcross": 0x0af4, + "musicalsharp": 0x0af5, + "musicalflat": 0x0af6, + "malesymbol": 0x0af7, + "femalesymbol": 0x0af8, + "telephone": 0x0af9, + "telephonerecorder": 0x0afa, + "phonographcopyright": 0x0afb, + "caret": 0x0afc, + "singlelowquotemark": 0x0afd, + "doublelowquotemark": 0x0afe, + "cursor": 0x0aff, + "leftcaret": 0x0ba3, + "rightcaret": 0x0ba6, + "downcaret": 0x0ba8, + "upcaret": 0x0ba9, + "overbar": 0x0bc0, + "downtack": 0x0bc2, + "upshoe": 0x0bc3, + "downstile": 0x0bc4, + "underbar": 0x0bc6, + "jot": 0x0bca, + "quad": 0x0bcc, + "uptack": 0x0bce, + "circle": 0x0bcf, + "upstile": 0x0bd3, + "downshoe": 0x0bd6, + "rightshoe": 0x0bd8, + "leftshoe": 0x0bda, + "lefttack": 0x0bdc, + "righttack": 0x0bfc, + "hebrew_doublelowline": 0x0cdf, + "hebrew_aleph": 0x0ce0, + "hebrew_bet": 0x0ce1, + "hebrew_beth": 0x0ce1, + "hebrew_gimel": 0x0ce2, + "hebrew_gimmel": 0x0ce2, + "hebrew_dalet": 0x0ce3, + "hebrew_daleth": 0x0ce3, + "hebrew_he": 0x0ce4, + "hebrew_waw": 0x0ce5, + "hebrew_zain": 0x0ce6, + "hebrew_zayin": 0x0ce6, + "hebrew_chet": 0x0ce7, + "hebrew_het": 0x0ce7, + "hebrew_tet": 0x0ce8, + "hebrew_teth": 0x0ce8, + "hebrew_yod": 0x0ce9, + "hebrew_finalkaph": 0x0cea, + "hebrew_kaph": 0x0ceb, + "hebrew_lamed": 0x0cec, + "hebrew_finalmem": 0x0ced, + "hebrew_mem": 0x0cee, + "hebrew_finalnun": 0x0cef, + "hebrew_nun": 0x0cf0, + "hebrew_samech": 0x0cf1, + "hebrew_samekh": 0x0cf1, + "hebrew_ayin": 0x0cf2, + "hebrew_finalpe": 0x0cf3, + "hebrew_pe": 0x0cf4, + "hebrew_finalzade": 0x0cf5, + "hebrew_finalzadi": 0x0cf5, + "hebrew_zade": 0x0cf6, + "hebrew_zadi": 0x0cf6, + "hebrew_qoph": 0x0cf7, + "hebrew_kuf": 0x0cf7, + "hebrew_resh": 0x0cf8, + "hebrew_shin": 0x0cf9, + "hebrew_taw": 0x0cfa, + "hebrew_taf": 0x0cfa, + "Hebrew_switch": 0xff7e, + "Thai_kokai": 0x0da1, + "Thai_khokhai": 0x0da2, + "Thai_khokhuat": 0x0da3, + "Thai_khokhwai": 0x0da4, + "Thai_khokhon": 0x0da5, + "Thai_khorakhang": 0x0da6, + "Thai_ngongu": 0x0da7, + "Thai_chochan": 0x0da8, + "Thai_choching": 0x0da9, + "Thai_chochang": 0x0daa, + "Thai_soso": 0x0dab, + "Thai_chochoe": 0x0dac, + "Thai_yoying": 0x0dad, + "Thai_dochada": 0x0dae, + "Thai_topatak": 0x0daf, + "Thai_thothan": 0x0db0, + "Thai_thonangmontho": 0x0db1, + "Thai_thophuthao": 0x0db2, + "Thai_nonen": 0x0db3, + "Thai_dodek": 0x0db4, + "Thai_totao": 0x0db5, + "Thai_thothung": 0x0db6, + "Thai_thothahan": 0x0db7, + "Thai_thothong": 0x0db8, + "Thai_nonu": 0x0db9, + "Thai_bobaimai": 0x0dba, + "Thai_popla": 0x0dbb, + "Thai_phophung": 0x0dbc, + "Thai_fofa": 0x0dbd, + "Thai_phophan": 0x0dbe, + "Thai_fofan": 0x0dbf, + "Thai_phosamphao": 0x0dc0, + "Thai_moma": 0x0dc1, + "Thai_yoyak": 0x0dc2, + "Thai_rorua": 0x0dc3, + "Thai_ru": 0x0dc4, + "Thai_loling": 0x0dc5, + "Thai_lu": 0x0dc6, + "Thai_wowaen": 0x0dc7, + "Thai_sosala": 0x0dc8, + "Thai_sorusi": 0x0dc9, + "Thai_sosua": 0x0dca, + "Thai_hohip": 0x0dcb, + "Thai_lochula": 0x0dcc, + "Thai_oang": 0x0dcd, + "Thai_honokhuk": 0x0dce, + "Thai_paiyannoi": 0x0dcf, + "Thai_saraa": 0x0dd0, + "Thai_maihanakat": 0x0dd1, + "Thai_saraaa": 0x0dd2, + "Thai_saraam": 0x0dd3, + "Thai_sarai": 0x0dd4, + "Thai_saraii": 0x0dd5, + "Thai_saraue": 0x0dd6, + "Thai_sarauee": 0x0dd7, + "Thai_sarau": 0x0dd8, + "Thai_sarauu": 0x0dd9, + "Thai_phinthu": 0x0dda, + "Thai_maihanakat_maitho": 0x0dde, + "Thai_baht": 0x0ddf, + "Thai_sarae": 0x0de0, + "Thai_saraae": 0x0de1, + "Thai_sarao": 0x0de2, + "Thai_saraaimaimuan": 0x0de3, + "Thai_saraaimaimalai": 0x0de4, + "Thai_lakkhangyao": 0x0de5, + "Thai_maiyamok": 0x0de6, + "Thai_maitaikhu": 0x0de7, + "Thai_maiek": 0x0de8, + "Thai_maitho": 0x0de9, + "Thai_maitri": 0x0dea, + "Thai_maichattawa": 0x0deb, + "Thai_thanthakhat": 0x0dec, + "Thai_nikhahit": 0x0ded, + "Thai_leksun": 0x0df0, + "Thai_leknung": 0x0df1, + "Thai_leksong": 0x0df2, + "Thai_leksam": 0x0df3, + "Thai_leksi": 0x0df4, + "Thai_lekha": 0x0df5, + "Thai_lekhok": 0x0df6, + "Thai_lekchet": 0x0df7, + "Thai_lekpaet": 0x0df8, + "Thai_lekkao": 0x0df9, + "Hangul": 0xff31, + "Hangul_Start": 0xff32, + "Hangul_End": 0xff33, + "Hangul_Hanja": 0xff34, + "Hangul_Jamo": 0xff35, + "Hangul_Romaja": 0xff36, + "Hangul_Codeinput": 0xff37, + "Hangul_Jeonja": 0xff38, + "Hangul_Banja": 0xff39, + "Hangul_PreHanja": 0xff3a, + "Hangul_PostHanja": 0xff3b, + "Hangul_SingleCandidate": 0xff3c, + "Hangul_MultipleCandidate": 0xff3d, + "Hangul_PreviousCandidate": 0xff3e, + "Hangul_Special": 0xff3f, + "Hangul_switch": 0xff7e, + "Hangul_Kiyeog": 0x0ea1, + "Hangul_SsangKiyeog": 0x0ea2, + "Hangul_KiyeogSios": 0x0ea3, + "Hangul_Nieun": 0x0ea4, + "Hangul_NieunJieuj": 0x0ea5, + "Hangul_NieunHieuh": 0x0ea6, + "Hangul_Dikeud": 0x0ea7, + "Hangul_SsangDikeud": 0x0ea8, + "Hangul_Rieul": 0x0ea9, + "Hangul_RieulKiyeog": 0x0eaa, + "Hangul_RieulMieum": 0x0eab, + "Hangul_RieulPieub": 0x0eac, + "Hangul_RieulSios": 0x0ead, + "Hangul_RieulTieut": 0x0eae, + "Hangul_RieulPhieuf": 0x0eaf, + "Hangul_RieulHieuh": 0x0eb0, + "Hangul_Mieum": 0x0eb1, + "Hangul_Pieub": 0x0eb2, + "Hangul_SsangPieub": 0x0eb3, + "Hangul_PieubSios": 0x0eb4, + "Hangul_Sios": 0x0eb5, + "Hangul_SsangSios": 0x0eb6, + "Hangul_Ieung": 0x0eb7, + "Hangul_Jieuj": 0x0eb8, + "Hangul_SsangJieuj": 0x0eb9, + "Hangul_Cieuc": 0x0eba, + "Hangul_Khieuq": 0x0ebb, + "Hangul_Tieut": 0x0ebc, + "Hangul_Phieuf": 0x0ebd, + "Hangul_Hieuh": 0x0ebe, + "Hangul_A": 0x0ebf, + "Hangul_AE": 0x0ec0, + "Hangul_YA": 0x0ec1, + "Hangul_YAE": 0x0ec2, + "Hangul_EO": 0x0ec3, + "Hangul_E": 0x0ec4, + "Hangul_YEO": 0x0ec5, + "Hangul_YE": 0x0ec6, + "Hangul_O": 0x0ec7, + "Hangul_WA": 0x0ec8, + "Hangul_WAE": 0x0ec9, + "Hangul_OE": 0x0eca, + "Hangul_YO": 0x0ecb, + "Hangul_U": 0x0ecc, + "Hangul_WEO": 0x0ecd, + "Hangul_WE": 0x0ece, + "Hangul_WI": 0x0ecf, + "Hangul_YU": 0x0ed0, + "Hangul_EU": 0x0ed1, + "Hangul_YI": 0x0ed2, + "Hangul_I": 0x0ed3, + "Hangul_J_Kiyeog": 0x0ed4, + "Hangul_J_SsangKiyeog": 0x0ed5, + "Hangul_J_KiyeogSios": 0x0ed6, + "Hangul_J_Nieun": 0x0ed7, + "Hangul_J_NieunJieuj": 0x0ed8, + "Hangul_J_NieunHieuh": 0x0ed9, + "Hangul_J_Dikeud": 0x0eda, + "Hangul_J_Rieul": 0x0edb, + "Hangul_J_RieulKiyeog": 0x0edc, + "Hangul_J_RieulMieum": 0x0edd, + "Hangul_J_RieulPieub": 0x0ede, + "Hangul_J_RieulSios": 0x0edf, + "Hangul_J_RieulTieut": 0x0ee0, + "Hangul_J_RieulPhieuf": 0x0ee1, + "Hangul_J_RieulHieuh": 0x0ee2, + "Hangul_J_Mieum": 0x0ee3, + "Hangul_J_Pieub": 0x0ee4, + "Hangul_J_PieubSios": 0x0ee5, + "Hangul_J_Sios": 0x0ee6, + "Hangul_J_SsangSios": 0x0ee7, + "Hangul_J_Ieung": 0x0ee8, + "Hangul_J_Jieuj": 0x0ee9, + "Hangul_J_Cieuc": 0x0eea, + "Hangul_J_Khieuq": 0x0eeb, + "Hangul_J_Tieut": 0x0eec, + "Hangul_J_Phieuf": 0x0eed, + "Hangul_J_Hieuh": 0x0eee, + "Hangul_RieulYeorinHieuh": 0x0eef, + "Hangul_SunkyeongeumMieum": 0x0ef0, + "Hangul_SunkyeongeumPieub": 0x0ef1, + "Hangul_PanSios": 0x0ef2, + "Hangul_KkogjiDalrinIeung": 0x0ef3, + "Hangul_SunkyeongeumPhieuf": 0x0ef4, + "Hangul_YeorinHieuh": 0x0ef5, + "Hangul_AraeA": 0x0ef6, + "Hangul_AraeAE": 0x0ef7, + "Hangul_J_PanSios": 0x0ef8, + "Hangul_J_KkogjiDalrinIeung": 0x0ef9, + "Hangul_J_YeorinHieuh": 0x0efa, + "Korean_Won": 0x0eff, + "Armenian_ligature_ew": 0x1000587, + "Armenian_full_stop": 0x1000589, + "Armenian_verjaket": 0x1000589, + "Armenian_separation_mark": 0x100055d, + "Armenian_but": 0x100055d, + "Armenian_hyphen": 0x100058a, + "Armenian_yentamna": 0x100058a, + "Armenian_exclam": 0x100055c, + "Armenian_amanak": 0x100055c, + "Armenian_accent": 0x100055b, + "Armenian_shesht": 0x100055b, + "Armenian_question": 0x100055e, + "Armenian_paruyk": 0x100055e, + "Armenian_AYB": 0x1000531, + "Armenian_ayb": 0x1000561, + "Armenian_BEN": 0x1000532, + "Armenian_ben": 0x1000562, + "Armenian_GIM": 0x1000533, + "Armenian_gim": 0x1000563, + "Armenian_DA": 0x1000534, + "Armenian_da": 0x1000564, + "Armenian_YECH": 0x1000535, + "Armenian_yech": 0x1000565, + "Armenian_ZA": 0x1000536, + "Armenian_za": 0x1000566, + "Armenian_E": 0x1000537, + "Armenian_e": 0x1000567, + "Armenian_AT": 0x1000538, + "Armenian_at": 0x1000568, + "Armenian_TO": 0x1000539, + "Armenian_to": 0x1000569, + "Armenian_ZHE": 0x100053a, + "Armenian_zhe": 0x100056a, + "Armenian_INI": 0x100053b, + "Armenian_ini": 0x100056b, + "Armenian_LYUN": 0x100053c, + "Armenian_lyun": 0x100056c, + "Armenian_KHE": 0x100053d, + "Armenian_khe": 0x100056d, + "Armenian_TSA": 0x100053e, + "Armenian_tsa": 0x100056e, + "Armenian_KEN": 0x100053f, + "Armenian_ken": 0x100056f, + "Armenian_HO": 0x1000540, + "Armenian_ho": 0x1000570, + "Armenian_DZA": 0x1000541, + "Armenian_dza": 0x1000571, + "Armenian_GHAT": 0x1000542, + "Armenian_ghat": 0x1000572, + "Armenian_TCHE": 0x1000543, + "Armenian_tche": 0x1000573, + "Armenian_MEN": 0x1000544, + "Armenian_men": 0x1000574, + "Armenian_HI": 0x1000545, + "Armenian_hi": 0x1000575, + "Armenian_NU": 0x1000546, + "Armenian_nu": 0x1000576, + "Armenian_SHA": 0x1000547, + "Armenian_sha": 0x1000577, + "Armenian_VO": 0x1000548, + "Armenian_vo": 0x1000578, + "Armenian_CHA": 0x1000549, + "Armenian_cha": 0x1000579, + "Armenian_PE": 0x100054a, + "Armenian_pe": 0x100057a, + "Armenian_JE": 0x100054b, + "Armenian_je": 0x100057b, + "Armenian_RA": 0x100054c, + "Armenian_ra": 0x100057c, + "Armenian_SE": 0x100054d, + "Armenian_se": 0x100057d, + "Armenian_VEV": 0x100054e, + "Armenian_vev": 0x100057e, + "Armenian_TYUN": 0x100054f, + "Armenian_tyun": 0x100057f, + "Armenian_RE": 0x1000550, + "Armenian_re": 0x1000580, + "Armenian_TSO": 0x1000551, + "Armenian_tso": 0x1000581, + "Armenian_VYUN": 0x1000552, + "Armenian_vyun": 0x1000582, + "Armenian_PYUR": 0x1000553, + "Armenian_pyur": 0x1000583, + "Armenian_KE": 0x1000554, + "Armenian_ke": 0x1000584, + "Armenian_O": 0x1000555, + "Armenian_o": 0x1000585, + "Armenian_FE": 0x1000556, + "Armenian_fe": 0x1000586, + "Armenian_apostrophe": 0x100055a, + "Georgian_an": 0x10010d0, + "Georgian_ban": 0x10010d1, + "Georgian_gan": 0x10010d2, + "Georgian_don": 0x10010d3, + "Georgian_en": 0x10010d4, + "Georgian_vin": 0x10010d5, + "Georgian_zen": 0x10010d6, + "Georgian_tan": 0x10010d7, + "Georgian_in": 0x10010d8, + "Georgian_kan": 0x10010d9, + "Georgian_las": 0x10010da, + "Georgian_man": 0x10010db, + "Georgian_nar": 0x10010dc, + "Georgian_on": 0x10010dd, + "Georgian_par": 0x10010de, + "Georgian_zhar": 0x10010df, + "Georgian_rae": 0x10010e0, + "Georgian_san": 0x10010e1, + "Georgian_tar": 0x10010e2, + "Georgian_un": 0x10010e3, + "Georgian_phar": 0x10010e4, + "Georgian_khar": 0x10010e5, + "Georgian_ghan": 0x10010e6, + "Georgian_qar": 0x10010e7, + "Georgian_shin": 0x10010e8, + "Georgian_chin": 0x10010e9, + "Georgian_can": 0x10010ea, + "Georgian_jil": 0x10010eb, + "Georgian_cil": 0x10010ec, + "Georgian_char": 0x10010ed, + "Georgian_xan": 0x10010ee, + "Georgian_jhan": 0x10010ef, + "Georgian_hae": 0x10010f0, + "Georgian_he": 0x10010f1, + "Georgian_hie": 0x10010f2, + "Georgian_we": 0x10010f3, + "Georgian_har": 0x10010f4, + "Georgian_hoe": 0x10010f5, + "Georgian_fi": 0x10010f6, + "Xabovedot": 0x1001e8a, + "Ibreve": 0x100012c, + "Zstroke": 0x10001b5, + "Gcaron": 0x10001e6, + "Ocaron": 0x10001d1, + "Obarred": 0x100019f, + "xabovedot": 0x1001e8b, + "ibreve": 0x100012d, + "zstroke": 0x10001b6, + "gcaron": 0x10001e7, + "ocaron": 0x10001d2, + "obarred": 0x1000275, + "SCHWA": 0x100018f, + "schwa": 0x1000259, + "Lbelowdot": 0x1001e36, + "lbelowdot": 0x1001e37, + "Abelowdot": 0x1001ea0, + "abelowdot": 0x1001ea1, + "Ahook": 0x1001ea2, + "ahook": 0x1001ea3, + "Acircumflexacute": 0x1001ea4, + "acircumflexacute": 0x1001ea5, + "Acircumflexgrave": 0x1001ea6, + "acircumflexgrave": 0x1001ea7, + "Acircumflexhook": 0x1001ea8, + "acircumflexhook": 0x1001ea9, + "Acircumflextilde": 0x1001eaa, + "acircumflextilde": 0x1001eab, + "Acircumflexbelowdot": 0x1001eac, + "acircumflexbelowdot": 0x1001ead, + "Abreveacute": 0x1001eae, + "abreveacute": 0x1001eaf, + "Abrevegrave": 0x1001eb0, + "abrevegrave": 0x1001eb1, + "Abrevehook": 0x1001eb2, + "abrevehook": 0x1001eb3, + "Abrevetilde": 0x1001eb4, + "abrevetilde": 0x1001eb5, + "Abrevebelowdot": 0x1001eb6, + "abrevebelowdot": 0x1001eb7, + "Ebelowdot": 0x1001eb8, + "ebelowdot": 0x1001eb9, + "Ehook": 0x1001eba, + "ehook": 0x1001ebb, + "Etilde": 0x1001ebc, + "etilde": 0x1001ebd, + "Ecircumflexacute": 0x1001ebe, + "ecircumflexacute": 0x1001ebf, + "Ecircumflexgrave": 0x1001ec0, + "ecircumflexgrave": 0x1001ec1, + "Ecircumflexhook": 0x1001ec2, + "ecircumflexhook": 0x1001ec3, + "Ecircumflextilde": 0x1001ec4, + "ecircumflextilde": 0x1001ec5, + "Ecircumflexbelowdot": 0x1001ec6, + "ecircumflexbelowdot": 0x1001ec7, + "Ihook": 0x1001ec8, + "ihook": 0x1001ec9, + "Ibelowdot": 0x1001eca, + "ibelowdot": 0x1001ecb, + "Obelowdot": 0x1001ecc, + "obelowdot": 0x1001ecd, + "Ohook": 0x1001ece, + "ohook": 0x1001ecf, + "Ocircumflexacute": 0x1001ed0, + "ocircumflexacute": 0x1001ed1, + "Ocircumflexgrave": 0x1001ed2, + "ocircumflexgrave": 0x1001ed3, + "Ocircumflexhook": 0x1001ed4, + "ocircumflexhook": 0x1001ed5, + "Ocircumflextilde": 0x1001ed6, + "ocircumflextilde": 0x1001ed7, + "Ocircumflexbelowdot": 0x1001ed8, + "ocircumflexbelowdot": 0x1001ed9, + "Ohornacute": 0x1001eda, + "ohornacute": 0x1001edb, + "Ohorngrave": 0x1001edc, + "ohorngrave": 0x1001edd, + "Ohornhook": 0x1001ede, + "ohornhook": 0x1001edf, + "Ohorntilde": 0x1001ee0, + "ohorntilde": 0x1001ee1, + "Ohornbelowdot": 0x1001ee2, + "ohornbelowdot": 0x1001ee3, + "Ubelowdot": 0x1001ee4, + "ubelowdot": 0x1001ee5, + "Uhook": 0x1001ee6, + "uhook": 0x1001ee7, + "Uhornacute": 0x1001ee8, + "uhornacute": 0x1001ee9, + "Uhorngrave": 0x1001eea, + "uhorngrave": 0x1001eeb, + "Uhornhook": 0x1001eec, + "uhornhook": 0x1001eed, + "Uhorntilde": 0x1001eee, + "uhorntilde": 0x1001eef, + "Uhornbelowdot": 0x1001ef0, + "uhornbelowdot": 0x1001ef1, + "Ybelowdot": 0x1001ef4, + "ybelowdot": 0x1001ef5, + "Yhook": 0x1001ef6, + "yhook": 0x1001ef7, + "Ytilde": 0x1001ef8, + "ytilde": 0x1001ef9, + "Ohorn": 0x10001a0, + "ohorn": 0x10001a1, + "Uhorn": 0x10001af, + "uhorn": 0x10001b0, + "EcuSign": 0x10020a0, + "ColonSign": 0x10020a1, + "CruzeiroSign": 0x10020a2, + "FFrancSign": 0x10020a3, + "LiraSign": 0x10020a4, + "MillSign": 0x10020a5, + "NairaSign": 0x10020a6, + "PesetaSign": 0x10020a7, + "RupeeSign": 0x10020a8, + "WonSign": 0x10020a9, + "NewSheqelSign": 0x10020aa, + "DongSign": 0x10020ab, + "EuroSign": 0x20ac, + "zerosuperior": 0x1002070, + "foursuperior": 0x1002074, + "fivesuperior": 0x1002075, + "sixsuperior": 0x1002076, + "sevensuperior": 0x1002077, + "eightsuperior": 0x1002078, + "ninesuperior": 0x1002079, + "zerosubscript": 0x1002080, + "onesubscript": 0x1002081, + "twosubscript": 0x1002082, + "threesubscript": 0x1002083, + "foursubscript": 0x1002084, + "fivesubscript": 0x1002085, + "sixsubscript": 0x1002086, + "sevensubscript": 0x1002087, + "eightsubscript": 0x1002088, + "ninesubscript": 0x1002089, + "partdifferential": 0x1002202, + "emptyset": 0x1002205, + "elementof": 0x1002208, + "notelementof": 0x1002209, + "containsas": 0x100220B, + "squareroot": 0x100221A, + "cuberoot": 0x100221B, + "fourthroot": 0x100221C, + "dintegral": 0x100222C, + "tintegral": 0x100222D, + "because": 0x1002235, + "approxeq": 0x1002248, + "notapproxeq": 0x1002247, + "notidentical": 0x1002262, + "stricteq": 0x1002263, + "braille_dot_1": 0xfff1, + "braille_dot_2": 0xfff2, + "braille_dot_3": 0xfff3, + "braille_dot_4": 0xfff4, + "braille_dot_5": 0xfff5, + "braille_dot_6": 0xfff6, + "braille_dot_7": 0xfff7, + "braille_dot_8": 0xfff8, + "braille_dot_9": 0xfff9, + "braille_dot_10": 0xfffa, + "braille_blank": 0x1002800, + "braille_dots_1": 0x1002801, + "braille_dots_2": 0x1002802, + "braille_dots_12": 0x1002803, + "braille_dots_3": 0x1002804, + "braille_dots_13": 0x1002805, + "braille_dots_23": 0x1002806, + "braille_dots_123": 0x1002807, + "braille_dots_4": 0x1002808, + "braille_dots_14": 0x1002809, + "braille_dots_24": 0x100280a, + "braille_dots_124": 0x100280b, + "braille_dots_34": 0x100280c, + "braille_dots_134": 0x100280d, + "braille_dots_234": 0x100280e, + "braille_dots_1234": 0x100280f, + "braille_dots_5": 0x1002810, + "braille_dots_15": 0x1002811, + "braille_dots_25": 0x1002812, + "braille_dots_125": 0x1002813, + "braille_dots_35": 0x1002814, + "braille_dots_135": 0x1002815, + "braille_dots_235": 0x1002816, + "braille_dots_1235": 0x1002817, + "braille_dots_45": 0x1002818, + "braille_dots_145": 0x1002819, + "braille_dots_245": 0x100281a, + "braille_dots_1245": 0x100281b, + "braille_dots_345": 0x100281c, + "braille_dots_1345": 0x100281d, + "braille_dots_2345": 0x100281e, + "braille_dots_12345": 0x100281f, + "braille_dots_6": 0x1002820, + "braille_dots_16": 0x1002821, + "braille_dots_26": 0x1002822, + "braille_dots_126": 0x1002823, + "braille_dots_36": 0x1002824, + "braille_dots_136": 0x1002825, + "braille_dots_236": 0x1002826, + "braille_dots_1236": 0x1002827, + "braille_dots_46": 0x1002828, + "braille_dots_146": 0x1002829, + "braille_dots_246": 0x100282a, + "braille_dots_1246": 0x100282b, + "braille_dots_346": 0x100282c, + "braille_dots_1346": 0x100282d, + "braille_dots_2346": 0x100282e, + "braille_dots_12346": 0x100282f, + "braille_dots_56": 0x1002830, + "braille_dots_156": 0x1002831, + "braille_dots_256": 0x1002832, + "braille_dots_1256": 0x1002833, + "braille_dots_356": 0x1002834, + "braille_dots_1356": 0x1002835, + "braille_dots_2356": 0x1002836, + "braille_dots_12356": 0x1002837, + "braille_dots_456": 0x1002838, + "braille_dots_1456": 0x1002839, + "braille_dots_2456": 0x100283a, + "braille_dots_12456": 0x100283b, + "braille_dots_3456": 0x100283c, + "braille_dots_13456": 0x100283d, + "braille_dots_23456": 0x100283e, + "braille_dots_123456": 0x100283f, + "braille_dots_7": 0x1002840, + "braille_dots_17": 0x1002841, + "braille_dots_27": 0x1002842, + "braille_dots_127": 0x1002843, + "braille_dots_37": 0x1002844, + "braille_dots_137": 0x1002845, + "braille_dots_237": 0x1002846, + "braille_dots_1237": 0x1002847, + "braille_dots_47": 0x1002848, + "braille_dots_147": 0x1002849, + "braille_dots_247": 0x100284a, + "braille_dots_1247": 0x100284b, + "braille_dots_347": 0x100284c, + "braille_dots_1347": 0x100284d, + "braille_dots_2347": 0x100284e, + "braille_dots_12347": 0x100284f, + "braille_dots_57": 0x1002850, + "braille_dots_157": 0x1002851, + "braille_dots_257": 0x1002852, + "braille_dots_1257": 0x1002853, + "braille_dots_357": 0x1002854, + "braille_dots_1357": 0x1002855, + "braille_dots_2357": 0x1002856, + "braille_dots_12357": 0x1002857, + "braille_dots_457": 0x1002858, + "braille_dots_1457": 0x1002859, + "braille_dots_2457": 0x100285a, + "braille_dots_12457": 0x100285b, + "braille_dots_3457": 0x100285c, + "braille_dots_13457": 0x100285d, + "braille_dots_23457": 0x100285e, + "braille_dots_123457": 0x100285f, + "braille_dots_67": 0x1002860, + "braille_dots_167": 0x1002861, + "braille_dots_267": 0x1002862, + "braille_dots_1267": 0x1002863, + "braille_dots_367": 0x1002864, + "braille_dots_1367": 0x1002865, + "braille_dots_2367": 0x1002866, + "braille_dots_12367": 0x1002867, + "braille_dots_467": 0x1002868, + "braille_dots_1467": 0x1002869, + "braille_dots_2467": 0x100286a, + "braille_dots_12467": 0x100286b, + "braille_dots_3467": 0x100286c, + "braille_dots_13467": 0x100286d, + "braille_dots_23467": 0x100286e, + "braille_dots_123467": 0x100286f, + "braille_dots_567": 0x1002870, + "braille_dots_1567": 0x1002871, + "braille_dots_2567": 0x1002872, + "braille_dots_12567": 0x1002873, + "braille_dots_3567": 0x1002874, + "braille_dots_13567": 0x1002875, + "braille_dots_23567": 0x1002876, + "braille_dots_123567": 0x1002877, + "braille_dots_4567": 0x1002878, + "braille_dots_14567": 0x1002879, + "braille_dots_24567": 0x100287a, + "braille_dots_124567": 0x100287b, + "braille_dots_34567": 0x100287c, + "braille_dots_134567": 0x100287d, + "braille_dots_234567": 0x100287e, + "braille_dots_1234567": 0x100287f, + "braille_dots_8": 0x1002880, + "braille_dots_18": 0x1002881, + "braille_dots_28": 0x1002882, + "braille_dots_128": 0x1002883, + "braille_dots_38": 0x1002884, + "braille_dots_138": 0x1002885, + "braille_dots_238": 0x1002886, + "braille_dots_1238": 0x1002887, + "braille_dots_48": 0x1002888, + "braille_dots_148": 0x1002889, + "braille_dots_248": 0x100288a, + "braille_dots_1248": 0x100288b, + "braille_dots_348": 0x100288c, + "braille_dots_1348": 0x100288d, + "braille_dots_2348": 0x100288e, + "braille_dots_12348": 0x100288f, + "braille_dots_58": 0x1002890, + "braille_dots_158": 0x1002891, + "braille_dots_258": 0x1002892, + "braille_dots_1258": 0x1002893, + "braille_dots_358": 0x1002894, + "braille_dots_1358": 0x1002895, + "braille_dots_2358": 0x1002896, + "braille_dots_12358": 0x1002897, + "braille_dots_458": 0x1002898, + "braille_dots_1458": 0x1002899, + "braille_dots_2458": 0x100289a, + "braille_dots_12458": 0x100289b, + "braille_dots_3458": 0x100289c, + "braille_dots_13458": 0x100289d, + "braille_dots_23458": 0x100289e, + "braille_dots_123458": 0x100289f, + "braille_dots_68": 0x10028a0, + "braille_dots_168": 0x10028a1, + "braille_dots_268": 0x10028a2, + "braille_dots_1268": 0x10028a3, + "braille_dots_368": 0x10028a4, + "braille_dots_1368": 0x10028a5, + "braille_dots_2368": 0x10028a6, + "braille_dots_12368": 0x10028a7, + "braille_dots_468": 0x10028a8, + "braille_dots_1468": 0x10028a9, + "braille_dots_2468": 0x10028aa, + "braille_dots_12468": 0x10028ab, + "braille_dots_3468": 0x10028ac, + "braille_dots_13468": 0x10028ad, + "braille_dots_23468": 0x10028ae, + "braille_dots_123468": 0x10028af, + "braille_dots_568": 0x10028b0, + "braille_dots_1568": 0x10028b1, + "braille_dots_2568": 0x10028b2, + "braille_dots_12568": 0x10028b3, + "braille_dots_3568": 0x10028b4, + "braille_dots_13568": 0x10028b5, + "braille_dots_23568": 0x10028b6, + "braille_dots_123568": 0x10028b7, + "braille_dots_4568": 0x10028b8, + "braille_dots_14568": 0x10028b9, + "braille_dots_24568": 0x10028ba, + "braille_dots_124568": 0x10028bb, + "braille_dots_34568": 0x10028bc, + "braille_dots_134568": 0x10028bd, + "braille_dots_234568": 0x10028be, + "braille_dots_1234568": 0x10028bf, + "braille_dots_78": 0x10028c0, + "braille_dots_178": 0x10028c1, + "braille_dots_278": 0x10028c2, + "braille_dots_1278": 0x10028c3, + "braille_dots_378": 0x10028c4, + "braille_dots_1378": 0x10028c5, + "braille_dots_2378": 0x10028c6, + "braille_dots_12378": 0x10028c7, + "braille_dots_478": 0x10028c8, + "braille_dots_1478": 0x10028c9, + "braille_dots_2478": 0x10028ca, + "braille_dots_12478": 0x10028cb, + "braille_dots_3478": 0x10028cc, + "braille_dots_13478": 0x10028cd, + "braille_dots_23478": 0x10028ce, + "braille_dots_123478": 0x10028cf, + "braille_dots_578": 0x10028d0, + "braille_dots_1578": 0x10028d1, + "braille_dots_2578": 0x10028d2, + "braille_dots_12578": 0x10028d3, + "braille_dots_3578": 0x10028d4, + "braille_dots_13578": 0x10028d5, + "braille_dots_23578": 0x10028d6, + "braille_dots_123578": 0x10028d7, + "braille_dots_4578": 0x10028d8, + "braille_dots_14578": 0x10028d9, + "braille_dots_24578": 0x10028da, + "braille_dots_124578": 0x10028db, + "braille_dots_34578": 0x10028dc, + "braille_dots_134578": 0x10028dd, + "braille_dots_234578": 0x10028de, + "braille_dots_1234578": 0x10028df, + "braille_dots_678": 0x10028e0, + "braille_dots_1678": 0x10028e1, + "braille_dots_2678": 0x10028e2, + "braille_dots_12678": 0x10028e3, + "braille_dots_3678": 0x10028e4, + "braille_dots_13678": 0x10028e5, + "braille_dots_23678": 0x10028e6, + "braille_dots_123678": 0x10028e7, + "braille_dots_4678": 0x10028e8, + "braille_dots_14678": 0x10028e9, + "braille_dots_24678": 0x10028ea, + "braille_dots_124678": 0x10028eb, + "braille_dots_34678": 0x10028ec, + "braille_dots_134678": 0x10028ed, + "braille_dots_234678": 0x10028ee, + "braille_dots_1234678": 0x10028ef, + "braille_dots_5678": 0x10028f0, + "braille_dots_15678": 0x10028f1, + "braille_dots_25678": 0x10028f2, + "braille_dots_125678": 0x10028f3, + "braille_dots_35678": 0x10028f4, + "braille_dots_135678": 0x10028f5, + "braille_dots_235678": 0x10028f6, + "braille_dots_1235678": 0x10028f7, + "braille_dots_45678": 0x10028f8, + "braille_dots_145678": 0x10028f9, + "braille_dots_245678": 0x10028fa, + "braille_dots_1245678": 0x10028fb, + "braille_dots_345678": 0x10028fc, + "braille_dots_1345678": 0x10028fd, + "braille_dots_2345678": 0x10028fe, + "braille_dots_12345678": 0x10028ff, + + "XF86ModeLock": 0x1008FF01, + "XF86MonBrightnessUp": 0x1008FF02, + "XF86MonBrightnessDown": 0x1008FF03, + "XF86KbdLightOnOff": 0x1008FF04, + "XF86KbdBrightnessUp": 0x1008FF05, + "XF86KbdBrightnessDown": 0x1008FF06, + "XF86Standby": 0x1008FF10, + "XF86AudioLowerVolume": 0x1008FF11, + "XF86AudioMute": 0x1008FF12, + "XF86AudioRaiseVolume": 0x1008FF13, + "XF86AudioPlay": 0x1008FF14, + "XF86AudioStop": 0x1008FF15, + "XF86AudioPrev": 0x1008FF16, + "XF86AudioNext": 0x1008FF17, + "XF86HomePage": 0x1008FF18, + "XF86Mail": 0x1008FF19, + "XF86Start": 0x1008FF1A, + "XF86Search": 0x1008FF1B, + "XF86AudioRecord": 0x1008FF1C, + "XF86Calculator": 0x1008FF1D, + "XF86Memo": 0x1008FF1E, + "XF86ToDoList": 0x1008FF1F, + "XF86Calendar": 0x1008FF20, + "XF86PowerDown": 0x1008FF21, + "XF86ContrastAdjust": 0x1008FF22, + "XF86RockerUp": 0x1008FF23, + "XF86RockerDown": 0x1008FF24, + "XF86RockerEnter": 0x1008FF25, + "XF86Back": 0x1008FF26, + "XF86Forward": 0x1008FF27, + "XF86Stop": 0x1008FF28, + "XF86Refresh": 0x1008FF29, + "XF86PowerOff": 0x1008FF2A, + "XF86WakeUp": 0x1008FF2B, + "XF86Eject": 0x1008FF2C, + "XF86ScreenSaver": 0x1008FF2D, + "XF86WWW": 0x1008FF2E, + "XF86Sleep": 0x1008FF2F, + "XF86Favorites": 0x1008FF30, + "XF86AudioPause": 0x1008FF31, + "XF86AudioMedia": 0x1008FF32, + "XF86MyComputer": 0x1008FF33, + "XF86VendorHome": 0x1008FF34, + "XF86LightBulb": 0x1008FF35, + "XF86Shop": 0x1008FF36, + "XF86History": 0x1008FF37, + "XF86OpenURL": 0x1008FF38, + "XF86AddFavorite": 0x1008FF39, + "XF86HotLinks": 0x1008FF3A, + "XF86BrightnessAdjust": 0x1008FF3B, + "XF86Finance": 0x1008FF3C, + "XF86Community": 0x1008FF3D, + "XF86AudioRewind": 0x1008FF3E, + "XF86BackForward": 0x1008FF3F, + "XF86Launch0": 0x1008FF40, + "XF86Launch1": 0x1008FF41, + "XF86Launch2": 0x1008FF42, + "XF86Launch3": 0x1008FF43, + "XF86Launch4": 0x1008FF44, + "XF86Launch5": 0x1008FF45, + "XF86Launch6": 0x1008FF46, + "XF86Launch7": 0x1008FF47, + "XF86Launch8": 0x1008FF48, + "XF86Launch9": 0x1008FF49, + "XF86LaunchA": 0x1008FF4A, + "XF86LaunchB": 0x1008FF4B, + "XF86LaunchC": 0x1008FF4C, + "XF86LaunchD": 0x1008FF4D, + "XF86LaunchE": 0x1008FF4E, + "XF86LaunchF": 0x1008FF4F, + "XF86ApplicationLeft": 0x1008FF50, + "XF86ApplicationRight": 0x1008FF51, + "XF86Book": 0x1008FF52, + "XF86CD": 0x1008FF53, + "XF86Calculater": 0x1008FF54, + "XF86Clear": 0x1008FF55, + "XF86Close": 0x1008FF56, + "XF86Copy": 0x1008FF57, + "XF86Cut": 0x1008FF58, + "XF86Display": 0x1008FF59, + "XF86DOS": 0x1008FF5A, + "XF86Documents": 0x1008FF5B, + "XF86Excel": 0x1008FF5C, + "XF86Explorer": 0x1008FF5D, + "XF86Game": 0x1008FF5E, + "XF86Go": 0x1008FF5F, + "XF86iTouch": 0x1008FF60, + "XF86LogOff": 0x1008FF61, + "XF86Market": 0x1008FF62, + "XF86Meeting": 0x1008FF63, + "XF86MenuKB": 0x1008FF65, + "XF86MenuPB": 0x1008FF66, + "XF86MySites": 0x1008FF67, + "XF86New": 0x1008FF68, + "XF86News": 0x1008FF69, + "XF86OfficeHome": 0x1008FF6A, + "XF86Open": 0x1008FF6B, + "XF86Option": 0x1008FF6C, + "XF86Paste": 0x1008FF6D, + "XF86Phone": 0x1008FF6E, + "XF86Q": 0x1008FF70, + "XF86Reply": 0x1008FF72, + "XF86Reload": 0x1008FF73, + "XF86RotateWindows": 0x1008FF74, + "XF86RotationPB": 0x1008FF75, + "XF86RotationKB": 0x1008FF76, + "XF86Save": 0x1008FF77, + "XF86ScrollUp": 0x1008FF78, + "XF86ScrollDown": 0x1008FF79, + "XF86ScrollClick": 0x1008FF7A, + "XF86Send": 0x1008FF7B, + "XF86Spell": 0x1008FF7C, + "XF86SplitScreen": 0x1008FF7D, + "XF86Support": 0x1008FF7E, + "XF86TaskPane": 0x1008FF7F, + "XF86Terminal": 0x1008FF80, + "XF86Tools": 0x1008FF81, + "XF86Travel": 0x1008FF82, + "XF86UserPB": 0x1008FF84, + "XF86User1KB": 0x1008FF85, + "XF86User2KB": 0x1008FF86, + "XF86Video": 0x1008FF87, + "XF86WheelButton": 0x1008FF88, + "XF86Word": 0x1008FF89, + "XF86Xfer": 0x1008FF8A, + "XF86ZoomIn": 0x1008FF8B, + "XF86ZoomOut": 0x1008FF8C, + "XF86Away": 0x1008FF8D, + "XF86Messenger": 0x1008FF8E, + "XF86WebCam": 0x1008FF8F, + "XF86MailForward": 0x1008FF90, + "XF86Pictures": 0x1008FF91, + "XF86Music": 0x1008FF92, + "XF86Battery": 0x1008FF93, + "XF86Bluetooth": 0x1008FF94, + "XF86WLAN": 0x1008FF95, + "XF86UWB": 0x1008FF96, + "XF86AudioForward": 0x1008FF97, + "XF86AudioRepeat": 0x1008FF98, + "XF86AudioRandomPlay": 0x1008FF99, + "XF86Subtitle": 0x1008FF9A, + "XF86AudioCycleTrack": 0x1008FF9B, + "XF86CycleAngle": 0x1008FF9C, + "XF86FrameBack": 0x1008FF9D, + "XF86FrameForward": 0x1008FF9E, + "XF86Time": 0x1008FF9F, + "XF86Select": 0x1008FFA0, + "XF86View": 0x1008FFA1, + "XF86TopMenu": 0x1008FFA2, + "XF86Red": 0x1008FFA3, + "XF86Green": 0x1008FFA4, + "XF86Yellow": 0x1008FFA5, + "XF86Blue": 0x1008FFA6, + "XF86Suspend": 0x1008FFA7, + "XF86Hibernate": 0x1008FFA8, + "XF86TouchpadToggle": 0x1008FFA9, + "XF86TouchpadOn": 0x1008FFB0, + "XF86TouchpadOff": 0x1008FFB1, + "XF86AudioMicMute": 0x1008FFB2, + "XF86Switch_VT_1": 0x1008FE01, + "XF86Switch_VT_2": 0x1008FE02, + "XF86Switch_VT_3": 0x1008FE03, + "XF86Switch_VT_4": 0x1008FE04, + "XF86Switch_VT_5": 0x1008FE05, + "XF86Switch_VT_6": 0x1008FE06, + "XF86Switch_VT_7": 0x1008FE07, + "XF86Switch_VT_8": 0x1008FE08, + "XF86Switch_VT_9": 0x1008FE09, + "XF86Switch_VT_10": 0x1008FE0A, + "XF86Switch_VT_11": 0x1008FE0B, + "XF86Switch_VT_12": 0x1008FE0C, + "XF86Ungrab": 0x1008FE20, + "XF86ClearGrab": 0x1008FE21, + "XF86Next_VMode": 0x1008FE22, + "XF86Prev_VMode": 0x1008FE23, + "XF86LogWindowTree": 0x1008FE24, + "XF86LogGrabInfo": 0x1008FE25, +} diff --git a/vend/xgbutil/keybind/xutil.go b/vend/xgbutil/keybind/xutil.go new file mode 100644 index 0000000..00ec9ba --- /dev/null +++ b/vend/xgbutil/keybind/xutil.go @@ -0,0 +1,172 @@ +package keybind + +/* +keybind/xutil.go contains a collection of functions that modify the +Keybinds and Keygrabs state of an XUtil value. + +They could have been placed inside the core xgbutil package, but they would +have to be exported for use by the keybind package. In which case, the API +would become cluttered with functions that should not be used. +*/ + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// attachKeyBindCallback associates an (event, window, mods, keycode) +// with a callback. +// This is exported for use in the keybind package. It should not be used. +func attachKeyBindCallback(xu *xgbutil.XUtil, evtype int, win xproto.Window, + mods uint16, keycode xproto.Keycode, fun xgbutil.CallbackKey) { + + xu.KeybindsLck.Lock() + defer xu.KeybindsLck.Unlock() + + // Create key + key := xgbutil.KeyKey{evtype, win, mods, keycode} + + // Do we need to allocate? + if _, ok := xu.Keybinds[key]; !ok { + xu.Keybinds[key] = make([]xgbutil.CallbackKey, 0) + } + + xu.Keybinds[key] = append(xu.Keybinds[key], fun) + xu.Keygrabs[key] += 1 +} + +// addKeyString adds a new key binding string to XUtil.Keystrings. +// The invariant is that each key string appears once and only once. +func addKeyString(xu *xgbutil.XUtil, callback xgbutil.CallbackKey, + evtype int, win xproto.Window, keyStr string, grab bool) { + + xu.KeybindsLck.Lock() + defer xu.KeybindsLck.Unlock() + + k := xgbutil.KeyString{ + Str: keyStr, + Callback: callback, + Evtype: evtype, + Win: win, + Grab: grab, + } + xu.Keystrings = append(xu.Keystrings, k) +} + +// keyBindKeys returns a copy of all the keys in the 'keybinds' map. +func keyKeys(xu *xgbutil.XUtil) []xgbutil.KeyKey { + xu.KeybindsLck.RLock() + defer xu.KeybindsLck.RUnlock() + + keys := make([]xgbutil.KeyKey, len(xu.Keybinds)) + i := 0 + for key, _ := range xu.Keybinds { + keys[i] = key + i++ + } + return keys +} + +// runKeyBindCallbacks executes every callback corresponding to a +// particular event/window/mod/key tuple. +// This is exported for use in the keybind package. It should not be used. +func runKeyBindCallbacks(xu *xgbutil.XUtil, event interface{}, evtype int, + win xproto.Window, mods uint16, keycode xproto.Keycode) { + + key := xgbutil.KeyKey{evtype, win, mods, keycode} + for _, cb := range keyCallbacks(xu, key) { + cb.Run(xu, event) + } +} + +// keyBindCallbacks returns a slice of callbacks for a particular key. +func keyCallbacks(xu *xgbutil.XUtil, + key xgbutil.KeyKey) []xgbutil.CallbackKey { + + xu.KeybindsLck.RLock() + defer xu.KeybindsLck.RUnlock() + + cbs := make([]xgbutil.CallbackKey, len(xu.Keybinds[key])) + copy(cbs, xu.Keybinds[key]) + return cbs +} + +// ConnectedKeyBind checks to see if there are any key binds for a particular +// event type already in play. +func connectedKeyBind(xu *xgbutil.XUtil, evtype int, win xproto.Window) bool { + xu.KeybindsLck.RLock() + defer xu.KeybindsLck.RUnlock() + + // Since we can't create a full key, loop through all key binds + // and check if evtype and window match. + for key, _ := range xu.Keybinds { + if key.Evtype == evtype && key.Win == win { + return true + } + } + return false +} + +// detachKeyBindWindow removes all callbacks associated with a particular +// window and event type (either KeyPress or KeyRelease) +// Also decrements the counter in the corresponding 'keygrabs' map +// appropriately. +// This is exported for use in the keybind package. It should not be used. +// To detach a window from a key binding callbacks, please use keybind.Detach. +// (This method will issue an Ungrab requests, while keybind.Detach will.) +func detachKeyBindWindow(xu *xgbutil.XUtil, evtype int, win xproto.Window) { + xu.KeybindsLck.Lock() + defer xu.KeybindsLck.Unlock() + + // Since we can't create a full key, loop through all key binds + // and check if evtype and window match. + for key, _ := range xu.Keybinds { + if key.Evtype == evtype && key.Win == win { + xu.Keygrabs[key] -= len(xu.Keybinds[key]) + delete(xu.Keybinds, key) + } + } +} + +// keyBindGrabs returns the number of grabs on a particular +// event/window/mods/keycode combination. Namely, this combination +// uniquely identifies a grab. If it's repeated, we get BadAccess. +// The idea is that if there are 0 grabs on a particular (modifiers, keycode) +// tuple, then we issue a grab request. Otherwise, we don't. +// This is exported for use in the keybind package. It should not be used. +func keyBindGrabs(xu *xgbutil.XUtil, evtype int, win xproto.Window, mods uint16, + keycode xproto.Keycode) int { + + xu.KeybindsLck.RLock() + defer xu.KeybindsLck.RUnlock() + + key := xgbutil.KeyKey{evtype, win, mods, keycode} + return xu.Keygrabs[key] // returns 0 if key does not exist +} + +// KeyMapGet accessor. +func KeyMapGet(xu *xgbutil.XUtil) *xgbutil.KeyboardMapping { + return xu.Keymap +} + +// KeyMapSet updates XUtil.keymap. +// This is exported for use in the keybind package. You probably shouldn't +// use this. (You may need to use this if you're rolling your own event loop, +// and still want to use the keybind package.) +func KeyMapSet(xu *xgbutil.XUtil, keyMapReply *xproto.GetKeyboardMappingReply) { + xu.Keymap = &xgbutil.KeyboardMapping{keyMapReply} +} + +// ModMapGet accessor. +func ModMapGet(xu *xgbutil.XUtil) *xgbutil.ModifierMapping { + return xu.Modmap +} + +// ModMapSet updates XUtil.modmap. +// This is exported for use in the keybind package. You probably shouldn't +// use this. (You may need to use this if you're rolling your own event loop, +// and still want to use the keybind package.) +func ModMapSet(xu *xgbutil.XUtil, modMapReply *xproto.GetModifierMappingReply) { + xu.Modmap = &xgbutil.ModifierMapping{modMapReply} +} diff --git a/vend/xgbutil/motif/motif.go b/vend/xgbutil/motif/motif.go new file mode 100644 index 0000000..e02a589 --- /dev/null +++ b/vend/xgbutil/motif/motif.go @@ -0,0 +1,128 @@ +/* +Package motif has a few functions to allow easy access to Motif related +properties. + +The main purpose here is that some applications communicate "no window +decorations" to the window manager using _MOTIF_WM_HINTS. (Like Google +Chrome.) I haven't seen Motif stuff used for other purposes in the wild for +a long time. + +As a result, only the useful bits are implemented here. More may be added +on an on-demand basis, but don't count on it. + +Try not to bash your head against your desk too hard: +http://www.opengroup.org/openmotif/hardcopydocs.html + +Example + +To test if a window wants decorations or not: + + mh, err := motif.WmHintsGet(XUtilValue, window-id) + if err != nil { + log.Fatal(err) + } else { + log.Println("Decorations? ", motif.Decor(mh)) + } + +*/ +package motif + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xprop" +) + +const ( + HintFunctions = (1 << iota) + HintDecorations + HintInputMode + HintStatus +) + +const ( + FunctionAll = (1 << iota) + FunctionResize + FunctionMove + FunctionMinimize + FunctionMaximize + FunctionClose + FunctionNone = 0 +) + +const ( + DecorationAll = (1 << iota) + DecorationBorder + DecorationResizeH + DecorationTitle + DecorationMenu + DecorationMinimize + DecorationMaximize + DecorationNone = 0 +) + +const ( + InputPrimaryApplicationModal = (1 << iota) + InputSystemModal + InputFullApplicationModal + InputModeless = 0 +) + +const StatusTearoffWindow = 1 + +// Decor checks a Hints value for whether or not the client has requested +// that the window manager paint decorations. +// That is, Decor returns false when the hints provided indicate no +// decorations and true otherwise. +func Decor(mh *Hints) bool { + if mh.Flags&HintDecorations > 0 { + noDecor := mh.Decoration == DecorationNone || + (mh.Decoration&DecorationAll == 0 && + mh.Decoration&DecorationTitle == 0 && + mh.Decoration&DecorationResizeH == 0) + return !noDecor + } + return true +} + +// Hints is a struct that organizes the information related to the +// WM_NORMAL_HINTS property. +type Hints struct { + Flags uint + Function, Decoration, Input, Status uint +} + +// _MOTIF_WM_HINTS get +func WmHintsGet(xu *xgbutil.XUtil, win xproto.Window) (mh *Hints, err error) { + lenExpect := 5 + hints, err := xprop.PropValNums(xprop.GetProperty(xu, win, + "_MOTIF_WM_HINTS")) + if err != nil { + return nil, err + } + if len(hints) != lenExpect { + return nil, + fmt.Errorf("motif.WmHintsGet: There are %d fields in "+ + "_MOTIF_WM_HINTS, but xgbutil expects %d.", + len(hints), lenExpect) + } + + mh = &Hints{} + mh.Flags = hints[0] + mh.Function = hints[1] + mh.Decoration = hints[2] + mh.Input = hints[3] + mh.Status = hints[4] + + return +} + +// _MOTIF_WM_HINTS set +func WmHintsSet(xu *xgbutil.XUtil, win xproto.Window, mh *Hints) error { + raw := []uint{mh.Flags, mh.Function, mh.Decoration, mh.Input, mh.Status} + return xprop.ChangeProp32(xu, win, "_MOTIF_WM_HINTS", "_MOTIF_WM_HINTS", + raw...) +} diff --git a/vend/xgbutil/mousebind/callback.go b/vend/xgbutil/mousebind/callback.go new file mode 100644 index 0000000..2a23a72 --- /dev/null +++ b/vend/xgbutil/mousebind/callback.go @@ -0,0 +1,178 @@ +package mousebind + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" +) + +// connect is essentially 'Connect' for either ButtonPress or +// ButtonRelease events. +func connect(xu *xgbutil.XUtil, callback xgbutil.CallbackMouse, evtype int, + win xproto.Window, buttonStr string, sync bool, grab bool) error { + + // Get the mods/button first + mods, button, err := ParseString(xu, buttonStr) + if err != nil { + return err + } + + // Only do the grab if we haven't yet on this window. + // And if we WANT a grab... + if grab && mouseBindGrabs(xu, evtype, win, mods, button) == 0 { + err := GrabChecked(xu, win, mods, button, sync) + if err != nil { + // If a bad access, let's be nice and give a good error message. + switch err.(type) { + case xproto.AccessError: + return fmt.Errorf("Got a bad access error when trying to bind "+ + "'%s'. This usually means another client has already "+ + "grabbed this mouse binding.", buttonStr) + default: + return fmt.Errorf("Could not bind '%s' because: %s", + buttonStr, err) + } + } + } + + // If we've never grabbed anything on this window before, we need to + // make sure we can respond to it in the main event loop. + var allCb xgbutil.Callback + if evtype == xevent.ButtonPress { + allCb = xevent.ButtonPressFun(runButtonPressCallbacks) + } else { + allCb = xevent.ButtonReleaseFun(runButtonReleaseCallbacks) + } + + // If this is the first Button{Press|Release}Event on this window, + // then we need to listen to Button{Press|Release} events in the main loop. + if !connectedMouseBind(xu, evtype, win) { + allCb.Connect(xu, win) + } + + // Finally, attach the callback. + attachMouseBindCallback(xu, evtype, win, mods, button, callback) + + return nil +} + +// DeduceButtonInfo takes a (modifiers, button) tuple and returns the relevant +// modifiers that were activated. This accounts for modifiers in +// xevent.IgnoreMods and the the button mask of the button that is pressed. +func DeduceButtonInfo(state uint16, + detail xproto.Button) (uint16, xproto.Button) { + + mods, button := state, detail + for _, m := range xevent.IgnoreMods { + mods &= ^m + } + + // We also need to mask out the button that has been pressed/released, + // since it is also typically a modifier. + modsTemp := int32(mods) + switch button { + case 1: + modsTemp &= ^xproto.ButtonMask1 + case 2: + modsTemp &= ^xproto.ButtonMask2 + case 3: + modsTemp &= ^xproto.ButtonMask3 + case 4: + modsTemp &= ^xproto.ButtonMask4 + case 5: + modsTemp &= ^xproto.ButtonMask5 + } + + return uint16(modsTemp), button +} + +// ButtonPressFun represents a function that is called when a particular mouse +// binding is fired. +type ButtonPressFun xevent.ButtonPressFun + +// If 'sync' is True, then no further events can be processed until the +// grabbing client allows them to be. (Which is done via AllowEvents. Thus, +// if sync is True, you *must* make some call to AllowEvents at some +// point, or else your client will lock.) +func (callback ButtonPressFun) Connect(xu *xgbutil.XUtil, win xproto.Window, + buttonStr string, sync bool, grab bool) error { + + return connect(xu, callback, xevent.ButtonPress, win, buttonStr, sync, grab) +} + +func (callback ButtonPressFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(xevent.ButtonPressEvent)) +} + +// ButtonReleaseFun represents a function that is called when a particular mouse +// binding is fired. +type ButtonReleaseFun xevent.ButtonReleaseFun + +// If 'sync' is True, then no further events can be processed until the +// grabbing client allows them to be. (Which is done via AllowEvents. Thus, +// if sync is True, you *must* make some call to AllowEvents at some +// point, or else your client will lock.) +func (callback ButtonReleaseFun) Connect(xu *xgbutil.XUtil, win xproto.Window, + buttonStr string, sync bool, grab bool) error { + + return connect(xu, callback, xevent.ButtonRelease, win, buttonStr, + sync, grab) +} + +func (callback ButtonReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(xevent.ButtonReleaseEvent)) +} + +// runButtonPressCallbacks infers the window, button and modifiers from a +// ButtonPressEvent and runs the corresponding callbacks. +func runButtonPressCallbacks(xu *xgbutil.XUtil, ev xevent.ButtonPressEvent) { + mods, button := DeduceButtonInfo(ev.State, ev.Detail) + + runMouseBindCallbacks(xu, ev, xevent.ButtonPress, ev.Event, mods, button) +} + +// runButtonReleaseCallbacks infers the window, keycode and modifiers from a +// ButtonPressEvent and runs the corresponding callbacks. +func runButtonReleaseCallbacks(xu *xgbutil.XUtil, + ev xevent.ButtonReleaseEvent) { + + mods, button := DeduceButtonInfo(ev.State, ev.Detail) + + runMouseBindCallbacks(xu, ev, xevent.ButtonRelease, ev.Event, mods, button) +} + +// Detach removes all handlers for all mouse events for the provided window id. +// This should be called whenever a window is no longer receiving events to make +// sure the garbage collector can release memory used to store the handler info. +func Detach(xu *xgbutil.XUtil, win xproto.Window) { + detach(xu, xevent.ButtonPress, win) + detach(xu, xevent.ButtonRelease, win) +} + +// DetachPress is the same as Detach, except it only removes handlers for +// button *press* events. +func DetachPress(xu *xgbutil.XUtil, win xproto.Window) { + detach(xu, xevent.ButtonPress, win) +} + +// DetachRelease is the same as Detach, except it only removes handlers for +// mouse *release* events. +func DetachRelease(xu *xgbutil.XUtil, win xproto.Window) { + detach(xu, xevent.ButtonRelease, win) +} + +// detach removes all handlers for the provided window and event type +// combination. This will also issue an ungrab request for each grab that +// drops to zero. +func detach(xu *xgbutil.XUtil, evtype int, win xproto.Window) { + mkeys := mouseKeys(xu) + detachMouseBindWindow(xu, evtype, win) + for _, key := range mkeys { + if mouseBindGrabs(xu, key.Evtype, key.Win, key.Mod, key.Button) == 0 { + Ungrab(xu, key.Win, key.Mod, key.Button) + } + } +} diff --git a/vend/xgbutil/mousebind/doc.go b/vend/xgbutil/mousebind/doc.go new file mode 100644 index 0000000..fc022ee --- /dev/null +++ b/vend/xgbutil/mousebind/doc.go @@ -0,0 +1,156 @@ +/* +Package mousebind provides an easy to use interface to assign callback functions +to human readable button sequences. + +Namely, the mousebind package exports two function types: ButtonPressFun and +ButtonReleaseFun. Values of these types are functions, and have a method called +'Connect' that attaches an event handler to be run when a particular button +press is issued. + +This is virtually identical to the way calbacks are attached using the xevent +package, but the Connect method in the mousebind package has a couple extra +parameters that are specific to mouse bindings. Namely, the button sequence to +respond to (which is a combination of zero or more modifiers and exactly one +button), whether to establish a passive grab and whether to make the grab +synchronous or not. One can still attach callbacks to Button{Press,Release} +events using xevent, but it will be run for *all* Button{Press,Release} events. +(This is typically what one might do when setting up an active grab.) + +Initialization + +Before using the mousebind package, you should *always* make a single call to +mousebind.Initialize for each X connection you're working with. + +Button sequence format + +Button sequences are human readable strings made up of zero or more modifiers +and exactly one button. Namely: + + [Mod[-Mod[...]]-]BUTTONNUMBER + +Where 'Mod' can be one of: shift, lock, control, mod1, mod2, mod3, mod4, mod5, +button1, button2, button3, button4, button5 or any. You can view which keys +activate each modifier using the 'xmodmap' program. (If you don't have +'xmodmap', you could also run the 'xmodmap' example in the examples directory.) +The 'button[1-5]' modifiers correspond to the button number in the name. (This +implies that buttons 1 through 5 can act as both a button number and a +modifier.) + +BUTTONNUMER must correspond to a valid button number on your mouse. The best +way to determine the numbers of each button on your mouse is to launch the xev +program in a terminal, click the corresponding button in the new window that +opens, and read the event output in the terminal that launched xev. Usually a +left click is button 1, a right click is button 3 and a middle click is button +2. + +An example button sequence might look like 'Mod4-Control-Shift-1'. The +mouse binding for that button sequence is activated when all three +modifiers---mod4, control and shift---are pressed along with the '1' button on +your mouse. + +When to issue a passive grab + +One of the parameters of the 'Connect' method is whether to issue a passive +grab or not. A passive grab is useful when you need to respond to a button press +on some parent window (like the root window) without actually focusing that +window. Not using a passive grab is useful when you only need to read button +presses when the window is focused. + +For more information on the semantics of passive grabs, please see +http://tronche.com/gui/x/xlib/input/XGrabButton.html. + +Also, by default, when issuing a grab on a particular (modifiers, button) +tuple, several grabs are actually made. In particular, for each grab requested, +another grab is made with the "num lock" mask, another grab is made with the +"caps lock" mask, and another grab is made with both the "num lock" and "caps +locks" masks. This allows button events to be reported regardless of whether +caps lock or num lock is enabled. + +The extra masks added can be modified by changing the xevent.IgnoreMods slice. +If you modify xevent.IgnoreMods, it should be modified once on program startup +(i.e., before any key or mouse bindings are established) and never modified +again. + +When to use a synchronous binding + +In the vast majority of cases, 'sync' in the 'Connect' method should be set to +false, which indicates that a passive grab should be asynchronous. (The value +of sync is irrelevant if 'grab' is false.) This implies that any events +generated by the grab are sent to the grabbing window (the second parameter of +the 'Connect' method) and only the grabbing window. + +Sometimes, however, you might want button events to cascade down the window +tree. That is, a button press on a parent window is grabbed, but then that +button press should be sent to any children windows. With an asynchronous grab, +this is impossible. With a synchronous grab, however, the button event can be +'replayed' to all child windows. For example: + + mousebind.Initialize(XUtilValue) // call once before using mousebind package + mousebind.ButtonPressFun( + func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { + // do something when button is pressed + // And now replay the pointer event that fired this handler to all + // child windows. All event processing is stopped on the + // X server until this is called. + xproto.AllowEvents(X.Conn(), xproto.AllowReplayPointer, 0) + }).Connect(XUtilValue, some-window-id, + "Mod4-Control-Shift-1", true, true) + +This sort of example is precisely how reparenting window managers allow one to +click on a window and have it be activated or "raised" *and* have the button +press sent to the client window as well. + +Note that with a synchronous grab, all event processing will be halted by the X +server until *some* call to xproto.AllowEvents is made. + +Mouse bindings on the root window example + +To run a particular function whenever the 'Mod4-Control-Shift-1' button +combination is pressed (mod4 is typically the 'super' or 'windows' key, but can +vary based on your system), use something like: + + mousebind.Initialize(XUtilValue) // call once before using mousebind package + mousebind.ButtonPressFun( + func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { + // do something when button is pressed + }).Connect(XUtilValue, XUtilValue.RootWin(), + "Mod4-Control-Shift-1", false, true) + +Note that we issue a passive grab because Button{Press,Release} events on the +root window will only be reported when the root window has focus if no grab +exists. + +Mouse bindings on a window you create example + +This code snippet attaches an event handler to some window you've created +without using a grab. Thus, the function will only be activated when the button +sequence is pressed and your window has focus. + + mousebind.Initialize(XUtilValue) // call once before using mousebind package + mousebind.ButtonPressFun( + func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { + // do something when button is pressed + }).Connect(XUtilValue, your-window-id, "Mod4-t", false, false) + +Run a function on all button press events example + +This code snippet actually does *not* use the mousebind package, but illustrates +how the Button{Press,Release} event handlers in the xevent package can still be +useful. Namely, the mousebind package discriminates among events depending upon +the button sequences pressed, whereas the xevent package is more general: it +can only discriminate at the event level. + + xevent.ButtonPressFun( + func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { + // do something when any button is pressed + }).Connect(XUtilValue, your-window-id) + +This is the kind of handler you might use to capture all button press events. + +More examples + +A complete working example using the mousebind package can be found in +'simple-mousebinding' in the examples directory of the xgbutil package. + +*/ +package mousebind diff --git a/vend/xgbutil/mousebind/drag.go b/vend/xgbutil/mousebind/drag.go new file mode 100644 index 0000000..87ded00 --- /dev/null +++ b/vend/xgbutil/mousebind/drag.go @@ -0,0 +1,159 @@ +package mousebind + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" +) + +// Drag is the public interface that will make the appropriate connections +// to register a drag event for three functions: the begin function, the +// step function and the end function. +// The 'grabwin' is the window that the grab is placed on (and therefore the +// window where all button events are redirected to after the drag has started), +// and the 'win' is the window that the initial 'begin' callback is set on. +// In typical use cases, these windows should be the same. +// If 'grab' is false, then no pointer grab is issued. +func Drag(xu *xgbutil.XUtil, grabwin xproto.Window, win xproto.Window, + buttonStr string, grab bool, + begin xgbutil.MouseDragBeginFun, step xgbutil.MouseDragFun, + end xgbutil.MouseDragFun) { + + ButtonPressFun( + func(xu *xgbutil.XUtil, ev xevent.ButtonPressEvent) { + DragBegin(xu, ev, grabwin, win, begin, step, end) + }).Connect(xu, win, buttonStr, false, grab) + + // If the grab win isn't the dummy, then setup event handlers for the + // grab window. + if grabwin != xu.Dummy() { + xevent.MotionNotifyFun(dragStep).Connect(xu, grabwin) + xevent.ButtonReleaseFun(DragEnd).Connect(xu, grabwin) + } +} + +// dragGrab is a shortcut for grabbing the pointer for a drag. +func dragGrab(xu *xgbutil.XUtil, grabwin xproto.Window, win xproto.Window, + cursor xproto.Cursor) bool { + + status, err := GrabPointer(xu, grabwin, xu.RootWin(), cursor) + if err != nil { + xgbutil.Logger.Printf("Mouse dragging was unsuccessful because: %v", + err) + return false + } + if !status { + xgbutil.Logger.Println("Mouse dragging was unsuccessful because " + + "we could not establish a pointer grab.") + return false + } + + mouseDragSet(xu, true) + return true +} + +// dragUngrab is a shortcut for ungrabbing the pointer for a drag. +func dragUngrab(xu *xgbutil.XUtil) { + UngrabPointer(xu) + mouseDragSet(xu, false) +} + +// DragBegin executes the "begin" function registered for the current drag. +// It also initiates the grab with the cursor id return by the begin callback. +// +// N.B. This function is automatically called in the Drag convenience function. +// This should be used when the drag can be started from a source other than +// a button press handled by the WM. If you use this function, then there +// should also be a call to DragEnd when the drag is done. (This is +// automatically done for you if you use Drag.) +func DragBegin(xu *xgbutil.XUtil, ev xevent.ButtonPressEvent, + grabwin xproto.Window, win xproto.Window, + begin xgbutil.MouseDragBeginFun, step xgbutil.MouseDragFun, + end xgbutil.MouseDragFun) { + + // don't start a drag if one is already in progress + if mouseDrag(xu) { + return + } + + // Run begin first. It may tell us to cancel the grab. + // It can also tell us which cursor to use when grabbing. + grab, cursor := begin(xu, int(ev.RootX), int(ev.RootY), + int(ev.EventX), int(ev.EventY)) + + // if we couldn't establish a grab, quit + // Or quit if 'begin' tells us to. + if !grab || !dragGrab(xu, grabwin, win, cursor) { + return + } + + // we're committed. set the drag state and start the 'begin' function + mouseDragStepSet(xu, step) + mouseDragEndSet(xu, end) +} + +// dragStep executes the "step" function registered for the current drag. +// It also compresses the MotionNotify events. +func dragStep(xu *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { + // If for whatever reason we don't have any *piece* of a grab, + // we've gotta back out. + if !mouseDrag(xu) || mouseDragStep(xu) == nil || mouseDragEnd(xu) == nil { + dragUngrab(xu) + mouseDragStepSet(xu, nil) + mouseDragEndSet(xu, nil) + return + } + + // The most recent MotionNotify event that we'll end up returning. + laste := ev + + // We force a round trip request so that we make sure to read all + // available events. + xu.Sync() + xevent.Read(xu, false) + + // Compress MotionNotify events. + for i, ee := range xevent.Peek(xu) { + if ee.Err != nil { // This is an error, skip it. + continue + } + + // Use type assertion to make sure this is a MotionNotify event. + if mn, ok := ee.Event.(xproto.MotionNotifyEvent); ok { + // Now make sure all appropriate fields are equivalent. + if ev.Event == mn.Event && ev.Child == mn.Child && + ev.Detail == mn.Detail && ev.State == mn.State && + ev.Root == mn.Root && ev.SameScreen == mn.SameScreen { + + // Set the most recent/valid motion notify event. + laste = xevent.MotionNotifyEvent{&mn} + + // We cheat and use the stack semantics of defer to dequeue + // most recent motion notify events first, so that the indices + // don't become invalid. (If we dequeued oldest first, we'd + // have to account for all future events shifting to the left + // by one.) + defer func(i int) { xevent.DequeueAt(xu, i) }(i) + } + } + } + xu.TimeSet(laste.Time) + + // now actually run the step + mouseDragStep(xu)(xu, int(laste.RootX), int(laste.RootY), + int(laste.EventX), int(laste.EventY)) +} + +// DragEnd executes the "end" function registered for the current drag. +// This must be called at some point if DragStart has been called. +func DragEnd(xu *xgbutil.XUtil, ev xevent.ButtonReleaseEvent) { + if mouseDragEnd(xu) != nil { + mouseDragEnd(xu)(xu, int(ev.RootX), int(ev.RootY), + int(ev.EventX), int(ev.EventY)) + } + + dragUngrab(xu) + mouseDragStepSet(xu, nil) + mouseDragEndSet(xu, nil) +} diff --git a/vend/xgbutil/mousebind/mousebind.go b/vend/xgbutil/mousebind/mousebind.go new file mode 100644 index 0000000..ff5a268 --- /dev/null +++ b/vend/xgbutil/mousebind/mousebind.go @@ -0,0 +1,171 @@ +package mousebind + +import ( + "fmt" + "strconv" + "strings" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xevent" +) + +var modifiers []uint16 = []uint16{ // order matters! + xproto.ModMaskShift, xproto.ModMaskLock, xproto.ModMaskControl, + xproto.ModMask1, xproto.ModMask2, xproto.ModMask3, + xproto.ModMask4, xproto.ModMask5, + xproto.ButtonMask1, xproto.ButtonMask2, xproto.ButtonMask3, + xproto.ButtonMask4, xproto.ButtonMask5, + xproto.ButtonMaskAny, +} + +var pointerMasks uint16 = xproto.EventMaskPointerMotion | + xproto.EventMaskButtonRelease | + xproto.EventMaskButtonPress + +// Initialize attaches the appropriate callbacks to make mouse bindings easier. +// i.e., prep the dummy window to handle mouse dragging events +func Initialize(xu *xgbutil.XUtil) { + xevent.MotionNotifyFun(dragStep).Connect(xu, xu.Dummy()) + xevent.ButtonReleaseFun(DragEnd).Connect(xu, xu.Dummy()) +} + +// ParseString takes a string of the format '[Mod[-Mod[...]]]-BUTTONNUMBER', +// i.e., 'Mod4-1', and returns a modifiers/button combination. +// "Mod" could also be one of {button1, button2, button3, button4, button5}. +// An error is returned if the string is malformed or if no BUTTONNUMBER +// could be found. +func ParseString(xu *xgbutil.XUtil, str string) (uint16, xproto.Button, error) { + mods, button := uint16(0), xproto.Button(0) + for _, part := range strings.Split(str, "-") { + switch strings.ToLower(part) { + case "shift": + mods |= xproto.ModMaskShift + case "lock": + mods |= xproto.ModMaskLock + case "control": + mods |= xproto.ModMaskControl + case "mod1": + mods |= xproto.ModMask1 + case "mod2": + mods |= xproto.ModMask2 + case "mod3": + mods |= xproto.ModMask3 + case "mod4": + mods |= xproto.ModMask4 + case "mod5": + mods |= xproto.ModMask5 + case "button1": + mods |= xproto.ButtonMask1 + case "button2": + mods |= xproto.ButtonMask2 + case "button3": + mods |= xproto.ButtonMask3 + case "button4": + mods |= xproto.ButtonMask4 + case "button5": + mods |= xproto.ButtonMask5 + case "any": + mods |= xproto.ButtonMaskAny + default: // a button! + if button == 0 { // only accept the first button we see + possible, err := strconv.ParseUint(part, 10, 8) + if err == nil { + button = xproto.Button(possible) + } else { + return 0, 0, fmt.Errorf("Could not convert '%s' to a "+ + "valid 8-bit integer.", part) + } + } + } + } + + if button == 0 { + return 0, 0, fmt.Errorf("Could not find a valid button in the "+ + "string '%s'. Mouse binding failed.", str) + } + + return mods, button, nil +} + +// Grab grabs a button with mods on a particular window. +// Will also grab all combinations of modifiers found in xevent.IgnoreMods +// If 'sync' is True, then no further events can be processed until the +// grabbing client allows them to be. (Which is done via AllowEvents. Thus, +// if sync is True, you *must* make some call to AllowEvents at some +// point, or else your client will lock.) +func Grab(xu *xgbutil.XUtil, win xproto.Window, mods uint16, + button xproto.Button, sync bool) { + + var pSync byte = xproto.GrabModeAsync + if sync { + pSync = xproto.GrabModeSync + } + + for _, m := range xevent.IgnoreMods { + xproto.GrabButton(xu.Conn(), true, win, pointerMasks, pSync, + xproto.GrabModeAsync, 0, 0, byte(button), mods|m) + } +} + +// GrabChecked grabs a button with mods on a particular window. It does the +// same thing as Grab, but issues a checked request and returns an error +// on failure. +// Will also grab all combinations of modifiers found in xevent.IgnoreMods +// If 'sync' is True, then no further events can be processed until the +// grabbing client allows them to be. (Which is done via AllowEvents. Thus, +// if sync is True, you *must* make some call to AllowEvents at some +// point, or else your client will lock.) +func GrabChecked(xu *xgbutil.XUtil, win xproto.Window, mods uint16, + button xproto.Button, sync bool) error { + + var pSync byte = xproto.GrabModeAsync + if sync { + pSync = xproto.GrabModeSync + } + + var err error + for _, m := range xevent.IgnoreMods { + err = xproto.GrabButtonChecked(xu.Conn(), true, win, pointerMasks, + pSync, xproto.GrabModeAsync, 0, 0, byte(button), mods|m).Check() + if err != nil { + return err + } + } + return nil +} + +// Ungrab undoes Grab. It will handle all combinations of modifiers found +// in xevent.IgnoreMods. +func Ungrab(xu *xgbutil.XUtil, win xproto.Window, mods uint16, + button xproto.Button) { + + for _, m := range xevent.IgnoreMods { + xproto.UngrabButtonChecked(xu.Conn(), byte(button), win, mods|m).Check() + } +} + +// GrabPointer grabs the entire pointer. +// Returns whether GrabStatus is successful and an error if one is reported by +// XGB. It is possible to not get an error and the grab to be unsuccessful. +// The purpose of 'win' is that after a grab is successful, ALL Button*Events +// will be sent to that window. Make sure you have a callback attached :-) +func GrabPointer(xu *xgbutil.XUtil, win xproto.Window, confine xproto.Window, + cursor xproto.Cursor) (bool, error) { + + reply, err := xproto.GrabPointer(xu.Conn(), false, win, pointerMasks, + xproto.GrabModeAsync, xproto.GrabModeAsync, + confine, cursor, 0).Reply() + if err != nil { + return false, fmt.Errorf("GrabPointer: Error grabbing pointer on "+ + "window '%x': %s", win, err) + } + + return reply.Status == xproto.GrabStatusSuccess, nil +} + +// UngrabPointer undoes GrabPointer. +func UngrabPointer(xu *xgbutil.XUtil) { + xproto.UngrabPointer(xu.Conn(), 0) +} diff --git a/vend/xgbutil/mousebind/xutil.go b/vend/xgbutil/mousebind/xutil.go new file mode 100644 index 0000000..a4c4262 --- /dev/null +++ b/vend/xgbutil/mousebind/xutil.go @@ -0,0 +1,153 @@ +package mousebind + +/* +mousebind/xutil.go contains a collection of functions that modify the +Mousebinds and Mousegrabs state of an XUtil value. + +They could have been placed inside the core xgbutil package, but they would +have to be exported for use by the mousebind package. In which case, the API +would become cluttered with functions that should not be used. +*/ + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// attachMouseBindCallback associates an (event, window, mods, button) +// with a callback. +func attachMouseBindCallback(xu *xgbutil.XUtil, evtype int, win xproto.Window, + mods uint16, button xproto.Button, fun xgbutil.CallbackMouse) { + + xu.MousebindsLck.Lock() + defer xu.MousebindsLck.Unlock() + + // Create key + key := xgbutil.MouseKey{evtype, win, mods, button} + + // Do we need to allocate? + if _, ok := xu.Mousebinds[key]; !ok { + xu.Mousebinds[key] = make([]xgbutil.CallbackMouse, 0) + } + + xu.Mousebinds[key] = append(xu.Mousebinds[key], fun) + xu.Mousegrabs[key] += 1 +} + +// mouseKeys returns a copy of all the keys in the 'Mousebinds' map. +func mouseKeys(xu *xgbutil.XUtil) []xgbutil.MouseKey { + xu.MousebindsLck.RLock() + defer xu.MousebindsLck.RUnlock() + + keys := make([]xgbutil.MouseKey, len(xu.Mousebinds)) + i := 0 + for key, _ := range xu.Mousebinds { + keys[i] = key + i++ + } + return keys +} + +// mouseBindCallbacks returns a slice of callbacks for a particular key. +func mouseCallbacks(xu *xgbutil.XUtil, + key xgbutil.MouseKey) []xgbutil.CallbackMouse { + + xu.MousebindsLck.RLock() + defer xu.MousebindsLck.RUnlock() + + cbs := make([]xgbutil.CallbackMouse, len(xu.Mousebinds[key])) + copy(cbs, xu.Mousebinds[key]) + return cbs +} + +// runMouseBindCallbacks executes every callback corresponding to a +// particular event/window/mod/button tuple. +func runMouseBindCallbacks(xu *xgbutil.XUtil, event interface{}, evtype int, + win xproto.Window, mods uint16, button xproto.Button) { + + key := xgbutil.MouseKey{evtype, win, mods, button} + for _, cb := range mouseCallbacks(xu, key) { + cb.Run(xu, event) + } +} + +// connectedMouseBind checks to see if there are any key binds for a particular +// event type already in play. This is to work around comparing function +// pointers (not allowed in Go), which would be used in 'Connected'. +func connectedMouseBind(xu *xgbutil.XUtil, evtype int, win xproto.Window) bool { + xu.MousebindsLck.RLock() + defer xu.MousebindsLck.RUnlock() + + // Since we can't create a full key, loop through all mouse binds + // and check if evtype and window match. + for key, _ := range xu.Mousebinds { + if key.Evtype == evtype && key.Win == win { + return true + } + } + return false +} + +// detachMouseBindWindow removes all callbacks associated with a particular +// window and event type (either ButtonPress or ButtonRelease) +// Also decrements the counter in the corresponding 'Mousegrabs' map +// appropriately. +func detachMouseBindWindow(xu *xgbutil.XUtil, evtype int, win xproto.Window) { + xu.MousebindsLck.Lock() + defer xu.MousebindsLck.Unlock() + + // Since we can't create a full key, loop through all mouse binds + // and check if evtype and window match. + for key, _ := range xu.Mousebinds { + if key.Evtype == evtype && key.Win == win { + xu.Mousegrabs[key] -= len(xu.Mousebinds[key]) + delete(xu.Mousebinds, key) + } + } +} + +// mouseBindGrabs returns the number of grabs on a particular +// event/window/mods/button combination. Namely, this combination +// uniquely identifies a grab. If it's repeated, we get BadAccess. +func mouseBindGrabs(xu *xgbutil.XUtil, evtype int, win xproto.Window, + mods uint16, button xproto.Button) int { + + xu.MousebindsLck.RLock() + defer xu.MousebindsLck.RUnlock() + + key := xgbutil.MouseKey{evtype, win, mods, button} + return xu.Mousegrabs[key] // returns 0 if key does not exist +} + +// mouseDrag true when a mouse drag is in progress. +func mouseDrag(xu *xgbutil.XUtil) bool { + return xu.InMouseDrag +} + +// mouseDragSet sets whether a mouse drag is in progress. +func mouseDragSet(xu *xgbutil.XUtil, dragging bool) { + xu.InMouseDrag = dragging +} + +// mouseDragStep returns the function currently associated with each +// step of a mouse drag. +func mouseDragStep(xu *xgbutil.XUtil) xgbutil.MouseDragFun { + return xu.MouseDragStepFun +} + +// mouseDragStepSet sets the function associated with the step of a drag. +func mouseDragStepSet(xu *xgbutil.XUtil, f xgbutil.MouseDragFun) { + xu.MouseDragStepFun = f +} + +// mouseDragEnd returns the function currently associated with the +// end of a mouse drag. +func mouseDragEnd(xu *xgbutil.XUtil) xgbutil.MouseDragFun { + return xu.MouseDragEndFun +} + +// mouseDragEndSet sets the function associated with the end of a drag. +func mouseDragEndSet(xu *xgbutil.XUtil, f xgbutil.MouseDragFun) { + xu.MouseDragEndFun = f +} diff --git a/vend/xgbutil/scripts/README b/vend/xgbutil/scripts/README new file mode 100644 index 0000000..71e9fd3 --- /dev/null +++ b/vend/xgbutil/scripts/README @@ -0,0 +1,16 @@ +The 'scripts' directory contains small programs that facilitate the development +of xgbutil. + +Currently, there is only one script: 'write-events'. + +write-events +============ +write-events is a short Python program that can automatically generates two +Go source files in the 'xevent' package. Namely, the 'types_auto.go' and +'callbacks.go' files. Both files contain a lot of boiler plate related to +definitions of each X event in the core protocol. + +If and when xgbutil adds support for other extensions (i.e., RandR), more +events will need to be added. + +'write-events' is run in when calling 'make' in the xgbutil root directory. diff --git a/vend/xgbutil/scripts/write-events b/vend/xgbutil/scripts/write-events new file mode 100755 index 0000000..56a2624 --- /dev/null +++ b/vend/xgbutil/scripts/write-events @@ -0,0 +1,125 @@ +#!/usr/bin/env python2.7 + +import sys + +events = [ + ('xproto', 'KeyPressEvent'), + ('xproto', 'KeyReleaseEvent'), + ('xproto', 'ButtonPressEvent'), + ('xproto', 'ButtonReleaseEvent'), + ('xproto', 'MotionNotifyEvent'), + ('xproto', 'EnterNotifyEvent'), + ('xproto', 'LeaveNotifyEvent'), + ('xproto', 'FocusInEvent'), + ('xproto', 'FocusOutEvent'), + ('xproto', 'KeymapNotifyEvent'), + ('xproto', 'ExposeEvent'), + ('xproto', 'GraphicsExposureEvent'), + ('xproto', 'NoExposureEvent'), + ('xproto', 'VisibilityNotifyEvent'), + ('xproto', 'CreateNotifyEvent'), + ('xproto', 'DestroyNotifyEvent'), + ('xproto', 'UnmapNotifyEvent'), + ('xproto', 'MapNotifyEvent'), + ('xproto', 'MapRequestEvent'), + ('xproto', 'ReparentNotifyEvent'), + ('xproto', 'ConfigureNotifyEvent'), + ('xproto', 'ConfigureRequestEvent'), + ('xproto', 'GravityNotifyEvent'), + ('xproto', 'ResizeRequestEvent'), + ('xproto', 'CirculateNotifyEvent'), + ('xproto', 'CirculateRequestEvent'), + ('xproto', 'PropertyNotifyEvent'), + ('xproto', 'SelectionClearEvent'), + ('xproto', 'SelectionRequestEvent'), + ('xproto', 'SelectionNotifyEvent'), + ('xproto', 'ColormapNotifyEvent'), + ('xproto', 'ClientMessageEvent'), + ('xproto', 'MappingNotifyEvent'), + + # X Shape extension events + ('shape', 'NotifyEvent'), +] + +assert len(sys.argv) == 2 + +if sys.argv[1] == 'evtypes': + print 'package xevent' + print '''/* + Defines event types and their associated methods automatically. + + This file is automatically generated using `scripts/write-events evtypes`. + + Edit it at your peril. +*/''' + print + print 'import (' + print '\t"fmt"' + print + print '\t"github.com/jezek/xgb/shape"' + print '\t"github.com/jezek/xgb/xproto"' + print ')' + print + + for ext, e in events: + # Skip ClientMessageEvent and ConfigureNotifyEvent + # We define these manually in xevents/types_manual.go + if e in ('ClientMessageEvent', 'ConfigureNotifyEvent'): + continue + + if ext == 'xproto': + print 'type %s struct {' % e + print ' *%s.%s' % (ext, e) + print '}' + print + print 'const %s = %s.%s' % (e[:-5], ext, e[:-5]) + print + print 'func (ev %s) String() string {' % e + print ' return fmt.Sprintf("%%v", ev.%s)' % e + print '}' + print + else: + print 'type %s%s struct {' % (ext.title(), e) + print ' *%s.%s' % (ext, e) + print '}' + print + print 'const %s%s = %s.%s' % (ext.title(), e[:-5], ext, e[:-5]) + print + print 'func (ev %s%s) String() string {' % (ext.title(), e) + print ' return fmt.Sprintf("%%v", ev.%s)' % e + print '}' + print +elif sys.argv[1] == 'callbacks': + print 'package xevent' + print '''/* + Does all the plumbing to allow a simple callback interface for users. + + This file is automatically generated using `scripts/write-events callbacks`. + + Edit it at your peril. +*/''' + print + print 'import (' + print '\t"github.com/jezek/xgb/xproto"' + print + print '\t"github.com/jezek/xgbutil"' + print ')' + print + + for ext, e in events: + e = e[:-5] + if ext != 'xproto': + e = '%s%s' % (ext.title(), e) + print 'type %sFun func(xu *xgbutil.XUtil, event %sEvent)' % (e, e) + print + print 'func (callback %sFun) '\ + 'Connect(xu *xgbutil.XUtil,\nwin xproto.Window) {' % e + print ' attachCallback(xu, %s, win, callback)' % e + print '}' + print + print 'func (callback %sFun) ' \ + 'Run(xu *xgbutil.XUtil, event interface{}) {' % e + print ' callback(xu, event.(%sEvent))' % e + print '}' + print + diff --git a/vend/xgbutil/session.vim b/vend/xgbutil/session.vim new file mode 100644 index 0000000..562164b --- /dev/null +++ b/vend/xgbutil/session.vim @@ -0,0 +1 @@ +au BufWritePost *.go silent!make tags > /dev/null 2>&1 diff --git a/vend/xgbutil/types.go b/vend/xgbutil/types.go new file mode 100644 index 0000000..0b53ce3 --- /dev/null +++ b/vend/xgbutil/types.go @@ -0,0 +1,167 @@ +package xgbutil + +/* +types.go contains several types used in the XUtil structure. In an ideal world, +they would be defined in their appropriate packages, but must be defined here +(and exported) for use in some sub-packages. (Namely, xevent, keybind and +mousebind.) +*/ + +import ( + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" +) + +// Callback is an interface that should be implemented by event callback +// functions. Namely, to assign a function to a particular event/window +// combination, simply define a function with type 'SomeEventFun' (pre-defined +// in xevent/callback.go), and call the 'Connect' method. +// The 'Run' method is used inside the Main event loop, and shouldn't be used +// by the user. +// Also, it is perfectly legitimate to connect to events that don't specify +// a window (like MappingNotify and KeymapNotify). In this case, simply +// use 'xgbutil.NoWindow' as the window id. +// +// Example to respond to ConfigureNotify events on window 0x1 +// +// xevent.ConfigureNotifyFun( +// func(X *xgbutil.XUtil, e xevent.ConfigureNotifyEvent) { +// fmt.Printf("(%d, %d) %dx%d\n", e.X, e.Y, e.Width, e.Height) +// }).Connect(X, 0x1) +type Callback interface { + // Connect modifies XUtil's state to attach an event handler to a + // particular event. + Connect(xu *XUtil, win xproto.Window) + + // Run is exported for use in the xevent package but should not be + // used by the user. (It is used to run the callback function in the + // main event loop.) + Run(xu *XUtil, ev interface{}) +} + +// CallbackHook works similarly to the more general Callback, but it is +// for hooks into the main xevent loop. As such it does not get attached +// to a window. +type CallbackHook interface { + // Connect connects this hook to the main loop of the passed XUtil + // instance. + Connect(xu *XUtil) + + // Run is exported for use in the xevent package, but should not be + // used by the user. It should return true if it's ok to process + // the event as usual, or false if it should be suppressed. + Run(xu *XUtil, ev interface{}) bool +} + +// CallbackKey works similarly to the more general Callback, but it adds +// parameters specific to key bindings. +type CallbackKey interface { + // Connect modifies XUtil's state to attach an event handler to a + // particular key press. If grab is true, connect will request a passive + // grab. + Connect(xu *XUtil, win xproto.Window, keyStr string, grab bool) error + + // Run is exported for use in the keybind package but should not be + // used by the user. (It is used to run the callback function in the + // main event loop. + Run(xu *XUtil, ev interface{}) +} + +// CallbackMouse works similarly to the more general Callback, but it adds +// parameters specific to mouse bindings. +type CallbackMouse interface { + // Connect modifies XUtil's state to attach an event handler to a + // particular button press. + // If sync is true, the grab will be synchronous. (This will require a + // call to xproto.AllowEvents in response, otherwise no further events + // will be processed and your program will lock.) + // If grab is true, connect will request a passive grab. + Connect(xu *XUtil, win xproto.Window, buttonStr string, + sync bool, grab bool) error + + // Run is exported for use in the mousebind package but should not be + // used by the user. (It is used to run the callback function in the + // main event loop.) + Run(xu *XUtil, ev interface{}) +} + +// KeyKey is the type of the key in the map of keybindings. +// It essentially represents the tuple +// (event type, window id, modifier, keycode). +// It is exported for use in the keybind package. It should not be used. +type KeyKey struct { + Evtype int + Win xproto.Window + Mod uint16 + Code xproto.Keycode +} + +// KeyString is the type of a key binding string used to connect to particular +// key combinations. A list of all such key strings is maintained in order to +// rebind keys when the keyboard mapping has been changed. +type KeyString struct { + Str string + Callback CallbackKey + Evtype int + Win xproto.Window + Grab bool +} + +// MouseKey is the type of the key in the map of mouse bindings. +// It essentially represents the tuple +// (event type, window id, modifier, button). +// It is exported for use in the mousebind package. It should not be used. +type MouseKey struct { + Evtype int + Win xproto.Window + Mod uint16 + Button xproto.Button +} + +// KeyboardMapping embeds a keyboard mapping reply from XGB. +// It should be retrieved using keybind.KeyMapGet, if necessary. +// xgbutil tries quite hard to absolve you from ever having to use this. +// A keyboard mapping is a table that maps keycodes to one or more keysyms. +type KeyboardMapping struct { + *xproto.GetKeyboardMappingReply +} + +// ModifierMapping embeds a modifier mapping reply from XGB. +// It should be retrieved using keybind.ModMapGet, if necessary. +// xgbutil tries quite hard to absolve you from ever having to use this. +// A modifier mapping is a table that maps modifiers to one or more keycodes. +type ModifierMapping struct { + *xproto.GetModifierMappingReply +} + +// ErrorHandlerFun is the type of function required to handle errors that +// come in through the main event loop. +// For example, to set a new error handler, use: +// +// xevent.ErrorHandlerSet(xgbutil.ErrorHandlerFun( +// func(err xgb.Error) { +// // do something with err +// })) +type ErrorHandlerFun func(err xgb.Error) + +// EventOrError is a struct that contains either an event value or an error +// value. It is an error to contain both. Containing neither indicates an +// error too. +// This is exported for use in the xevent package. You shouldn't have any +// direct contact with values of this type, unless you need to inspect the +// queue directly with xevent.Peek. +type EventOrError struct { + Event xgb.Event + Err xgb.Error +} + +// MouseDragFun is the kind of function used on each dragging step +// and at the end of a drag. +type MouseDragFun func(xu *XUtil, rootX, rootY, eventX, eventY int) + +// MouseDragBeginFun is the kind of function used to initialize a drag. +// The difference between this and MouseDragFun is that the begin function +// returns a bool (of whether or not to cancel the drag) and an X resource +// identifier corresponding to a cursor. +type MouseDragBeginFun func(xu *XUtil, rootX, rootY, + eventX, eventY int) (bool, xproto.Cursor) diff --git a/vend/xgbutil/xcursor/cursordef.go b/vend/xgbutil/xcursor/cursordef.go new file mode 100644 index 0000000..a031f59 --- /dev/null +++ b/vend/xgbutil/xcursor/cursordef.go @@ -0,0 +1,81 @@ +package xcursor + +const ( + XCursor = 0 + Arrow = 2 + BasedArrowDown = 4 + BasedArrowUp = 6 + Boat = 8 + Bogosity = 10 + BottomLeftCorner = 12 + BottomRightCorner = 14 + BottomSide = 16 + BottomTee = 18 + BoxSpiral = 20 + CenterPtr = 22 + Circle = 24 + Clock = 26 + CoffeeMug = 28 + Cross = 30 + CrossReverse = 32 + Crosshair = 34 + DiamondCross = 36 + Dot = 38 + DotBoxMask = 40 + DoubleArrow = 42 + DraftLarge = 44 + DraftSmall = 46 + DrapedBox = 48 + Exchange = 50 + Fleur = 52 + Gobbler = 54 + Gumby = 56 + Hand1 = 58 + Hand2 = 60 + Heart = 62 + Icon = 64 + IronCross = 66 + LeftPtr = 68 + LeftSide = 70 + LeftTee = 72 + LeftButton = 74 + LLAngle = 76 + LRAngle = 78 + Man = 80 + MiddleButton = 82 + Mouse = 84 + Pencil = 86 + Pirate = 88 + Plus = 90 + QuestionArrow = 92 + RightPtr = 94 + RightSide = 96 + RightTee = 98 + RightButton = 100 + RtlLogo = 102 + Sailboat = 104 + SBDownArrow = 106 + SBHDoubleArrow = 108 + SBLeftArrow = 110 + SBRightArrow = 112 + SBUpArrow = 114 + SBVDoubleArrow = 116 + Shuttle = 118 + Sizing = 120 + Spider = 122 + Spraycan = 124 + Star = 126 + Target = 128 + TCross = 130 + TopLeftArrow = 132 + TopLeftCorner = 134 + TopRightCorner = 136 + TopSide = 138 + TopTee = 140 + Trek = 142 + ULAngle = 144 + Umbrella = 146 + URAngle = 148 + Watch = 150 + XTerm = 152 +) diff --git a/vend/xgbutil/xcursor/doc.go b/vend/xgbutil/xcursor/doc.go new file mode 100644 index 0000000..7e00bd9 --- /dev/null +++ b/vend/xgbutil/xcursor/doc.go @@ -0,0 +1,11 @@ +/* +Package xcursor provides a small interface for using cursors that are +predefined in the X 'cursor' font. + +All available cursors are predefined in cursordef.go. + +Please see the 'change-cursor' example in the examples directory of the xgbutil +package for an example of how to change the cursor when it enters a particular +window. +*/ +package xcursor diff --git a/vend/xgbutil/xcursor/xcursor.go b/vend/xgbutil/xcursor/xcursor.go new file mode 100644 index 0000000..50b3ea9 --- /dev/null +++ b/vend/xgbutil/xcursor/xcursor.go @@ -0,0 +1,53 @@ +package xcursor + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// CreateCursor sets some default colors for nice and easy cursor creation. +// Just supply a cursor constant from 'xcursor/cursordef.go'. +func CreateCursor(xu *xgbutil.XUtil, cursor uint16) (xproto.Cursor, error) { + return CreateCursorExtra(xu, cursor, 0, 0, 0, 0xffff, 0xffff, 0xffff) +} + +// CreateCursorExtra features all available parameters to creating a cursor. +// It will return an error if there is a problem with any of the requests +// made to create the cursor. +// (This implies each request is a checked request. The performance loss is +// probably acceptable since cursors should be created once and reused.) +func CreateCursorExtra(xu *xgbutil.XUtil, cursor, foreRed, foreGreen, + foreBlue, backRed, backGreen, backBlue uint16) (xproto.Cursor, error) { + + fontId, err := xproto.NewFontId(xu.Conn()) + if err != nil { + return 0, err + } + + cursorId, err := xproto.NewCursorId(xu.Conn()) + if err != nil { + return 0, err + } + + err = xproto.OpenFontChecked(xu.Conn(), fontId, + uint16(len("cursor")), "cursor").Check() + if err != nil { + return 0, err + } + + err = xproto.CreateGlyphCursorChecked(xu.Conn(), cursorId, fontId, fontId, + cursor, cursor+1, + foreRed, foreGreen, foreBlue, + backRed, backGreen, backBlue).Check() + if err != nil { + return 0, err + } + + err = xproto.CloseFontChecked(xu.Conn(), fontId).Check() + if err != nil { + return 0, err + } + + return cursorId, nil +} diff --git a/vend/xgbutil/xevent/callback.go b/vend/xgbutil/xevent/callback.go new file mode 100644 index 0000000..a56411c --- /dev/null +++ b/vend/xgbutil/xevent/callback.go @@ -0,0 +1,389 @@ +package xevent + +/* + Does all the plumbing to allow a simple callback interface for users. + + This file is automatically generated using `scripts/write-events callbacks`. + + Edit it at your peril. +*/ + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +type KeyPressFun func(xu *xgbutil.XUtil, event KeyPressEvent) + +func (callback KeyPressFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, KeyPress, win, callback) +} + +func (callback KeyPressFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(KeyPressEvent)) +} + +type KeyReleaseFun func(xu *xgbutil.XUtil, event KeyReleaseEvent) + +func (callback KeyReleaseFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, KeyRelease, win, callback) +} + +func (callback KeyReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(KeyReleaseEvent)) +} + +type ButtonPressFun func(xu *xgbutil.XUtil, event ButtonPressEvent) + +func (callback ButtonPressFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ButtonPress, win, callback) +} + +func (callback ButtonPressFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ButtonPressEvent)) +} + +type ButtonReleaseFun func(xu *xgbutil.XUtil, event ButtonReleaseEvent) + +func (callback ButtonReleaseFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ButtonRelease, win, callback) +} + +func (callback ButtonReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ButtonReleaseEvent)) +} + +type MotionNotifyFun func(xu *xgbutil.XUtil, event MotionNotifyEvent) + +func (callback MotionNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, MotionNotify, win, callback) +} + +func (callback MotionNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(MotionNotifyEvent)) +} + +type EnterNotifyFun func(xu *xgbutil.XUtil, event EnterNotifyEvent) + +func (callback EnterNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, EnterNotify, win, callback) +} + +func (callback EnterNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(EnterNotifyEvent)) +} + +type LeaveNotifyFun func(xu *xgbutil.XUtil, event LeaveNotifyEvent) + +func (callback LeaveNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, LeaveNotify, win, callback) +} + +func (callback LeaveNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(LeaveNotifyEvent)) +} + +type FocusInFun func(xu *xgbutil.XUtil, event FocusInEvent) + +func (callback FocusInFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, FocusIn, win, callback) +} + +func (callback FocusInFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(FocusInEvent)) +} + +type FocusOutFun func(xu *xgbutil.XUtil, event FocusOutEvent) + +func (callback FocusOutFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, FocusOut, win, callback) +} + +func (callback FocusOutFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(FocusOutEvent)) +} + +type KeymapNotifyFun func(xu *xgbutil.XUtil, event KeymapNotifyEvent) + +func (callback KeymapNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, KeymapNotify, win, callback) +} + +func (callback KeymapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(KeymapNotifyEvent)) +} + +type ExposeFun func(xu *xgbutil.XUtil, event ExposeEvent) + +func (callback ExposeFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, Expose, win, callback) +} + +func (callback ExposeFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ExposeEvent)) +} + +type GraphicsExposureFun func(xu *xgbutil.XUtil, event GraphicsExposureEvent) + +func (callback GraphicsExposureFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, GraphicsExposure, win, callback) +} + +func (callback GraphicsExposureFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(GraphicsExposureEvent)) +} + +type NoExposureFun func(xu *xgbutil.XUtil, event NoExposureEvent) + +func (callback NoExposureFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, NoExposure, win, callback) +} + +func (callback NoExposureFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(NoExposureEvent)) +} + +type VisibilityNotifyFun func(xu *xgbutil.XUtil, event VisibilityNotifyEvent) + +func (callback VisibilityNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, VisibilityNotify, win, callback) +} + +func (callback VisibilityNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(VisibilityNotifyEvent)) +} + +type CreateNotifyFun func(xu *xgbutil.XUtil, event CreateNotifyEvent) + +func (callback CreateNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, CreateNotify, win, callback) +} + +func (callback CreateNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(CreateNotifyEvent)) +} + +type DestroyNotifyFun func(xu *xgbutil.XUtil, event DestroyNotifyEvent) + +func (callback DestroyNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, DestroyNotify, win, callback) +} + +func (callback DestroyNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(DestroyNotifyEvent)) +} + +type UnmapNotifyFun func(xu *xgbutil.XUtil, event UnmapNotifyEvent) + +func (callback UnmapNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, UnmapNotify, win, callback) +} + +func (callback UnmapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(UnmapNotifyEvent)) +} + +type MapNotifyFun func(xu *xgbutil.XUtil, event MapNotifyEvent) + +func (callback MapNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, MapNotify, win, callback) +} + +func (callback MapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(MapNotifyEvent)) +} + +type MapRequestFun func(xu *xgbutil.XUtil, event MapRequestEvent) + +func (callback MapRequestFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, MapRequest, win, callback) +} + +func (callback MapRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(MapRequestEvent)) +} + +type ReparentNotifyFun func(xu *xgbutil.XUtil, event ReparentNotifyEvent) + +func (callback ReparentNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ReparentNotify, win, callback) +} + +func (callback ReparentNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ReparentNotifyEvent)) +} + +type ConfigureNotifyFun func(xu *xgbutil.XUtil, event ConfigureNotifyEvent) + +func (callback ConfigureNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ConfigureNotify, win, callback) +} + +func (callback ConfigureNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ConfigureNotifyEvent)) +} + +type ConfigureRequestFun func(xu *xgbutil.XUtil, event ConfigureRequestEvent) + +func (callback ConfigureRequestFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ConfigureRequest, win, callback) +} + +func (callback ConfigureRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ConfigureRequestEvent)) +} + +type GravityNotifyFun func(xu *xgbutil.XUtil, event GravityNotifyEvent) + +func (callback GravityNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, GravityNotify, win, callback) +} + +func (callback GravityNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(GravityNotifyEvent)) +} + +type ResizeRequestFun func(xu *xgbutil.XUtil, event ResizeRequestEvent) + +func (callback ResizeRequestFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ResizeRequest, win, callback) +} + +func (callback ResizeRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ResizeRequestEvent)) +} + +type CirculateNotifyFun func(xu *xgbutil.XUtil, event CirculateNotifyEvent) + +func (callback CirculateNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, CirculateNotify, win, callback) +} + +func (callback CirculateNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(CirculateNotifyEvent)) +} + +type CirculateRequestFun func(xu *xgbutil.XUtil, event CirculateRequestEvent) + +func (callback CirculateRequestFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, CirculateRequest, win, callback) +} + +func (callback CirculateRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(CirculateRequestEvent)) +} + +type PropertyNotifyFun func(xu *xgbutil.XUtil, event PropertyNotifyEvent) + +func (callback PropertyNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, PropertyNotify, win, callback) +} + +func (callback PropertyNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(PropertyNotifyEvent)) +} + +type SelectionClearFun func(xu *xgbutil.XUtil, event SelectionClearEvent) + +func (callback SelectionClearFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, SelectionClear, win, callback) +} + +func (callback SelectionClearFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(SelectionClearEvent)) +} + +type SelectionRequestFun func(xu *xgbutil.XUtil, event SelectionRequestEvent) + +func (callback SelectionRequestFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, SelectionRequest, win, callback) +} + +func (callback SelectionRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(SelectionRequestEvent)) +} + +type SelectionNotifyFun func(xu *xgbutil.XUtil, event SelectionNotifyEvent) + +func (callback SelectionNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, SelectionNotify, win, callback) +} + +func (callback SelectionNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(SelectionNotifyEvent)) +} + +type ColormapNotifyFun func(xu *xgbutil.XUtil, event ColormapNotifyEvent) + +func (callback ColormapNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ColormapNotify, win, callback) +} + +func (callback ColormapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ColormapNotifyEvent)) +} + +type ClientMessageFun func(xu *xgbutil.XUtil, event ClientMessageEvent) + +func (callback ClientMessageFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ClientMessage, win, callback) +} + +func (callback ClientMessageFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ClientMessageEvent)) +} + +type MappingNotifyFun func(xu *xgbutil.XUtil, event MappingNotifyEvent) + +func (callback MappingNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, MappingNotify, win, callback) +} + +func (callback MappingNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(MappingNotifyEvent)) +} + +type ShapeNotifyFun func(xu *xgbutil.XUtil, event ShapeNotifyEvent) + +func (callback ShapeNotifyFun) Connect(xu *xgbutil.XUtil, + win xproto.Window) { + attachCallback(xu, ShapeNotify, win, callback) +} + +func (callback ShapeNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { + callback(xu, event.(ShapeNotifyEvent)) +} diff --git a/vend/xgbutil/xevent/doc.go b/vend/xgbutil/xevent/doc.go new file mode 100644 index 0000000..eee7c13 --- /dev/null +++ b/vend/xgbutil/xevent/doc.go @@ -0,0 +1,76 @@ +/* +Package xevent provides an event handler interface for attaching callback +functions to X events, and an implementation of an X event loop. + +The X event loop + +One of the biggest conveniences offered by xgbutil is its event handler system. +That is, the ability to attach an arbitrary callback function to any X event. +In order for such things to work, xgbutil needs to control the main X event +loop and act as a dispatcher for all event handlers created by you. + +To run the X event loop, use xevent.Main or xevent.MainPing. The former +runs a normal event loop in the current goroutine and processes events. The +latter runs the event loop in a new goroutine and returns a pingBefore and +a pingAfter channel. The pingBefore channel is sent a benign value right before +an event is dequeued, and the pingAfter channel is sent a benign value right +after after all callbacks for that event have finished execution. These +synchronization points in the main event loop can be combined with a 'select' +statement to process data from other input sources. An example of this is given +in the documentation for the MainPing function. A complete example called +multiple-source-event-loop can also be found in the examples directory of the +xgbutil package. + +To quit the main event loop, you may use xevent.Quit, but there is nothing +inherently wrong with stopping dead using os.Exit. xevent.Quit is provided for +your convenience should you need to run any clean-up code after the main event +loop returns. + +The X event queue + +xgbutil's event queue contains values that are either events or errors. (Never +both and never neither.) Namely, errors are received in the event loop from +unchecked requests. (Errors generated by checked requests are guaranteed to be +returned to the caller and are never received in the event loop.) Also, a +default error handler function can be set with xevent.ErrorHandlerSet. + +To this end, xgbutil's event queue can be inspected. This is advantageous when +information about what events will be processed in the future could be helpful +(i.e., if there is an UnmapNotify event waiting to be processed.) The event +queue can also be manipulated to facilitate event compression. (Two events that +are common candidates for compression are ConfigureNotify and MotionNotify.) + +Detach events + +Whenever a window can no longer receive events (i.e., when it is destroyed), +all event handlers related to that window should be detached. (If this is +omitted, then Go's garbage collector will not be able to reuse memory occupied +by the now-unused event handlers for that window.) Moreover, its possible that +a window id can be reused after it has been discarded, which could result in +odd behavior in your application. + +To detach a window from all event handlers in the xevent package, use +xevent.Detach. If you're also using the keybind and mousebind packages, you'll +need to call keybind.Detach and mousebind.Detach too. So to detach your window +from all possible event handlers in xgbutil, use something like: + + xevent.Detach(XUtilValue, your-window-id) + keybind.Detach(XUtilValue, your-window-id) + mousebind.Detach(XUtilValue, your-window-id) + +Quick example + +A small example that shows how to respond to ConfigureNotify events sent to +your-window-id. + + xevent.ConfigureNotifyFun( + func(X *xgbutil.XUtil, e xevent.ConfigureNotifyEvent) { + fmt.Printf("(%d, %d) %dx%d\n", e.X, e.Y, e.Width, e.Height) + }).Connect(XUtilValue, your-window-id) + +More examples + +The xevent package is used in several of the examples in the examples directory +in the xgbutil package. +*/ +package xevent diff --git a/vend/xgbutil/xevent/eventloop.go b/vend/xgbutil/xevent/eventloop.go new file mode 100644 index 0000000..3e2a656 --- /dev/null +++ b/vend/xgbutil/xevent/eventloop.go @@ -0,0 +1,291 @@ +package xevent + +/* +xevent/eventloop.go contains code that implements a main X event loop. + +Namely, it provides facilities to read new events into xevent's event queue, +run a normal main event loop and run a main event loop that pings a channel +each time an event is about to be dequeued. The latter facility allows one to +easily include other input sources for processing in a program's main event +loop. +*/ + +import ( + "github.com/jezek/xgb/shape" + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// Read reads one or more events and queues them in XUtil. +// If 'block' is True, then call 'WaitForEvent' before sucking up +// all events that have been queued by XGB. +func Read(xu *xgbutil.XUtil, block bool) { + if block { + ev, err := xu.Conn().WaitForEvent() + if ev == nil && err == nil { + xgbutil.Logger.Fatal("BUG: Could not read an event or an error.") + } + Enqueue(xu, ev, err) + } + + // Clean up anything that's in the queue + for { + ev, err := xu.Conn().PollForEvent() + + // No events left... + if ev == nil && err == nil { + break + } + + // We're good, queue it up + Enqueue(xu, ev, err) + } +} + +// Main starts the main X event loop. It will read events and call appropriate +// callback functions. +// N.B. If you have multiple X connections in the same program, you should be +// able to run this in different goroutines concurrently. However, only +// *one* of these should run for *each* connection. +func Main(xu *xgbutil.XUtil) { + mainEventLoop(xu, nil, nil, nil) +} + +// MainPing starts the main X event loop, and returns three "ping" channels: +// the first is pinged before an event is dequeued, the second is pinged +// after all callbacks for a particular event have been called and the last +// is pinged when the event loop stops (e.g., after a call to xevent.Quit). +// pingAfter channel. +// +// This is useful if your event loop needs to draw from other sources. e.g., +// +// pingBefore, pingAfter, pingQuit := xevent.MainPing() +// for { +// select { +// case <-pingBefore: +// // Wait for event processing to finish. +// <-pingAfter +// case val <- someOtherChannel: +// // do some work with val +// case <-pingQuit: +// fmt.Printf("xevent loop has quit") +// return +// } +// } +// +// Note that an unbuffered channel is returned, which implies that any work +// done with 'val' will delay further X event processing. +// +// A complete example using MainPing can be found in the examples directory in +// the xgbutil package under the name multiple-source-event-loop. +func MainPing(xu *xgbutil.XUtil) (chan struct{}, chan struct{}, chan struct{}) { + pingBefore := make(chan struct{}, 0) + pingAfter := make(chan struct{}, 0) + pingQuit := make(chan struct{}, 0) + go func() { + mainEventLoop(xu, pingBefore, pingAfter, pingQuit) + }() + return pingBefore, pingAfter, pingQuit +} + +// mainEventLoop runs the main event loop with an optional ping channel. +func mainEventLoop(xu *xgbutil.XUtil, + pingBefore, pingAfter, pingQuit chan struct{}) { + for { + if Quitting(xu) { + if pingQuit != nil { + pingQuit <- struct{}{} + } + break + } + + // Gobble up as many events as possible (into the queue). + // If there are no events, we block. + Read(xu, true) + + // Now process every event/error in the queue. + processEventQueue(xu, pingBefore, pingAfter) + } +} + +// processEventQueue processes every item in the event/error queue. +func processEventQueue(xu *xgbutil.XUtil, pingBefore, pingAfter chan struct{}) { + for !Empty(xu) { + if Quitting(xu) { + return + } + + // We send the ping *before* the next event is dequeued. + // This is so the queue doesn't present a misrepresentation of which + // events haven't been processed yet. + if pingBefore != nil && pingAfter != nil { + pingBefore <- struct{}{} + } + ev, err := Dequeue(xu) + + // If we gobbled up an error, send it to the error event handler + // and move on the next event/error. + if err != nil { + ErrorHandlerGet(xu)(err) + if pingBefore != nil && pingAfter != nil { + pingAfter <- struct{}{} + } + continue + } + + // We know there isn't an error. If there isn't an event either, + // then there's a bug somewhere. + if ev == nil { + xgbutil.Logger.Fatal("BUG: Expected an event but got nil.") + } + + hooks := getHooks(xu) + for _, hook := range hooks { + if !hook.Run(xu, ev) { + goto END + } + } + + switch event := ev.(type) { + case xproto.KeyPressEvent: + e := KeyPressEvent{&event} + + // If we're redirecting key events, this is the place to do it! + if wid := RedirectKeyGet(xu); wid > 0 { + e.Event = wid + } + + xu.TimeSet(e.Time) + runCallbacks(xu, e, KeyPress, e.Event) + case xproto.KeyReleaseEvent: + e := KeyReleaseEvent{&event} + + // If we're redirecting key events, this is the place to do it! + if wid := RedirectKeyGet(xu); wid > 0 { + e.Event = wid + } + + xu.TimeSet(e.Time) + runCallbacks(xu, e, KeyRelease, e.Event) + case xproto.ButtonPressEvent: + e := ButtonPressEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, ButtonPress, e.Event) + case xproto.ButtonReleaseEvent: + e := ButtonReleaseEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, ButtonRelease, e.Event) + case xproto.MotionNotifyEvent: + e := MotionNotifyEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, MotionNotify, e.Event) + case xproto.EnterNotifyEvent: + e := EnterNotifyEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, EnterNotify, e.Event) + case xproto.LeaveNotifyEvent: + e := LeaveNotifyEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, LeaveNotify, e.Event) + case xproto.FocusInEvent: + e := FocusInEvent{&event} + runCallbacks(xu, e, FocusIn, e.Event) + case xproto.FocusOutEvent: + e := FocusOutEvent{&event} + runCallbacks(xu, e, FocusOut, e.Event) + case xproto.KeymapNotifyEvent: + e := KeymapNotifyEvent{&event} + runCallbacks(xu, e, KeymapNotify, NoWindow) + case xproto.ExposeEvent: + e := ExposeEvent{&event} + runCallbacks(xu, e, Expose, e.Window) + case xproto.GraphicsExposureEvent: + e := GraphicsExposureEvent{&event} + runCallbacks(xu, e, GraphicsExposure, xproto.Window(e.Drawable)) + case xproto.NoExposureEvent: + e := NoExposureEvent{&event} + runCallbacks(xu, e, NoExposure, xproto.Window(e.Drawable)) + case xproto.VisibilityNotifyEvent: + e := VisibilityNotifyEvent{&event} + runCallbacks(xu, e, VisibilityNotify, e.Window) + case xproto.CreateNotifyEvent: + e := CreateNotifyEvent{&event} + runCallbacks(xu, e, CreateNotify, e.Parent) + case xproto.DestroyNotifyEvent: + e := DestroyNotifyEvent{&event} + runCallbacks(xu, e, DestroyNotify, e.Window) + case xproto.UnmapNotifyEvent: + e := UnmapNotifyEvent{&event} + runCallbacks(xu, e, UnmapNotify, e.Window) + case xproto.MapNotifyEvent: + e := MapNotifyEvent{&event} + runCallbacks(xu, e, MapNotify, e.Event) + case xproto.MapRequestEvent: + e := MapRequestEvent{&event} + runCallbacks(xu, e, MapRequest, e.Window) + runCallbacks(xu, e, MapRequest, e.Parent) + case xproto.ReparentNotifyEvent: + e := ReparentNotifyEvent{&event} + runCallbacks(xu, e, ReparentNotify, e.Window) + case xproto.ConfigureNotifyEvent: + e := ConfigureNotifyEvent{&event} + runCallbacks(xu, e, ConfigureNotify, e.Window) + case xproto.ConfigureRequestEvent: + e := ConfigureRequestEvent{&event} + runCallbacks(xu, e, ConfigureRequest, e.Window) + runCallbacks(xu, e, ConfigureRequest, e.Parent) + case xproto.GravityNotifyEvent: + e := GravityNotifyEvent{&event} + runCallbacks(xu, e, GravityNotify, e.Window) + case xproto.ResizeRequestEvent: + e := ResizeRequestEvent{&event} + runCallbacks(xu, e, ResizeRequest, e.Window) + case xproto.CirculateNotifyEvent: + e := CirculateNotifyEvent{&event} + runCallbacks(xu, e, CirculateNotify, e.Window) + case xproto.CirculateRequestEvent: + e := CirculateRequestEvent{&event} + runCallbacks(xu, e, CirculateRequest, e.Window) + case xproto.PropertyNotifyEvent: + e := PropertyNotifyEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, PropertyNotify, e.Window) + case xproto.SelectionClearEvent: + e := SelectionClearEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, SelectionClear, e.Owner) + case xproto.SelectionRequestEvent: + e := SelectionRequestEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, SelectionRequest, e.Owner) + case xproto.SelectionNotifyEvent: + e := SelectionNotifyEvent{&event} + xu.TimeSet(e.Time) + runCallbacks(xu, e, SelectionNotify, e.Requestor) + case xproto.ColormapNotifyEvent: + e := ColormapNotifyEvent{&event} + runCallbacks(xu, e, ColormapNotify, e.Window) + case xproto.ClientMessageEvent: + e := ClientMessageEvent{&event} + runCallbacks(xu, e, ClientMessage, e.Window) + case xproto.MappingNotifyEvent: + e := MappingNotifyEvent{&event} + runCallbacks(xu, e, MappingNotify, NoWindow) + case shape.NotifyEvent: + e := ShapeNotifyEvent{&event} + runCallbacks(xu, e, ShapeNotify, e.AffectedWindow) + default: + if event != nil { + xgbutil.Logger.Printf("ERROR: UNSUPPORTED EVENT TYPE: %T", + event) + } + } + + END: + + if pingBefore != nil && pingAfter != nil { + pingAfter <- struct{}{} + } + } +} diff --git a/vend/xgbutil/xevent/types_auto.go b/vend/xgbutil/xevent/types_auto.go new file mode 100644 index 0000000..de23ed7 --- /dev/null +++ b/vend/xgbutil/xevent/types_auto.go @@ -0,0 +1,336 @@ +package xevent + +/* + Defines event types and their associated methods automatically. + + This file is automatically generated using `scripts/write-events evtypes`. + + Edit it at your peril. +*/ + +import ( + "fmt" + + "github.com/jezek/xgb/shape" + "github.com/jezek/xgb/xproto" +) + +type KeyPressEvent struct { + *xproto.KeyPressEvent +} + +const KeyPress = xproto.KeyPress + +func (ev KeyPressEvent) String() string { + return fmt.Sprintf("%v", ev.KeyPressEvent) +} + +type KeyReleaseEvent struct { + *xproto.KeyReleaseEvent +} + +const KeyRelease = xproto.KeyRelease + +func (ev KeyReleaseEvent) String() string { + return fmt.Sprintf("%v", ev.KeyReleaseEvent) +} + +type ButtonPressEvent struct { + *xproto.ButtonPressEvent +} + +const ButtonPress = xproto.ButtonPress + +func (ev ButtonPressEvent) String() string { + return fmt.Sprintf("%v", ev.ButtonPressEvent) +} + +type ButtonReleaseEvent struct { + *xproto.ButtonReleaseEvent +} + +const ButtonRelease = xproto.ButtonRelease + +func (ev ButtonReleaseEvent) String() string { + return fmt.Sprintf("%v", ev.ButtonReleaseEvent) +} + +type MotionNotifyEvent struct { + *xproto.MotionNotifyEvent +} + +const MotionNotify = xproto.MotionNotify + +func (ev MotionNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.MotionNotifyEvent) +} + +type EnterNotifyEvent struct { + *xproto.EnterNotifyEvent +} + +const EnterNotify = xproto.EnterNotify + +func (ev EnterNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.EnterNotifyEvent) +} + +type LeaveNotifyEvent struct { + *xproto.LeaveNotifyEvent +} + +const LeaveNotify = xproto.LeaveNotify + +func (ev LeaveNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.LeaveNotifyEvent) +} + +type FocusInEvent struct { + *xproto.FocusInEvent +} + +const FocusIn = xproto.FocusIn + +func (ev FocusInEvent) String() string { + return fmt.Sprintf("%v", ev.FocusInEvent) +} + +type FocusOutEvent struct { + *xproto.FocusOutEvent +} + +const FocusOut = xproto.FocusOut + +func (ev FocusOutEvent) String() string { + return fmt.Sprintf("%v", ev.FocusOutEvent) +} + +type KeymapNotifyEvent struct { + *xproto.KeymapNotifyEvent +} + +const KeymapNotify = xproto.KeymapNotify + +func (ev KeymapNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.KeymapNotifyEvent) +} + +type ExposeEvent struct { + *xproto.ExposeEvent +} + +const Expose = xproto.Expose + +func (ev ExposeEvent) String() string { + return fmt.Sprintf("%v", ev.ExposeEvent) +} + +type GraphicsExposureEvent struct { + *xproto.GraphicsExposureEvent +} + +const GraphicsExposure = xproto.GraphicsExposure + +func (ev GraphicsExposureEvent) String() string { + return fmt.Sprintf("%v", ev.GraphicsExposureEvent) +} + +type NoExposureEvent struct { + *xproto.NoExposureEvent +} + +const NoExposure = xproto.NoExposure + +func (ev NoExposureEvent) String() string { + return fmt.Sprintf("%v", ev.NoExposureEvent) +} + +type VisibilityNotifyEvent struct { + *xproto.VisibilityNotifyEvent +} + +const VisibilityNotify = xproto.VisibilityNotify + +func (ev VisibilityNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.VisibilityNotifyEvent) +} + +type CreateNotifyEvent struct { + *xproto.CreateNotifyEvent +} + +const CreateNotify = xproto.CreateNotify + +func (ev CreateNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.CreateNotifyEvent) +} + +type DestroyNotifyEvent struct { + *xproto.DestroyNotifyEvent +} + +const DestroyNotify = xproto.DestroyNotify + +func (ev DestroyNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.DestroyNotifyEvent) +} + +type UnmapNotifyEvent struct { + *xproto.UnmapNotifyEvent +} + +const UnmapNotify = xproto.UnmapNotify + +func (ev UnmapNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.UnmapNotifyEvent) +} + +type MapNotifyEvent struct { + *xproto.MapNotifyEvent +} + +const MapNotify = xproto.MapNotify + +func (ev MapNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.MapNotifyEvent) +} + +type MapRequestEvent struct { + *xproto.MapRequestEvent +} + +const MapRequest = xproto.MapRequest + +func (ev MapRequestEvent) String() string { + return fmt.Sprintf("%v", ev.MapRequestEvent) +} + +type ReparentNotifyEvent struct { + *xproto.ReparentNotifyEvent +} + +const ReparentNotify = xproto.ReparentNotify + +func (ev ReparentNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.ReparentNotifyEvent) +} + +type ConfigureRequestEvent struct { + *xproto.ConfigureRequestEvent +} + +const ConfigureRequest = xproto.ConfigureRequest + +func (ev ConfigureRequestEvent) String() string { + return fmt.Sprintf("%v", ev.ConfigureRequestEvent) +} + +type GravityNotifyEvent struct { + *xproto.GravityNotifyEvent +} + +const GravityNotify = xproto.GravityNotify + +func (ev GravityNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.GravityNotifyEvent) +} + +type ResizeRequestEvent struct { + *xproto.ResizeRequestEvent +} + +const ResizeRequest = xproto.ResizeRequest + +func (ev ResizeRequestEvent) String() string { + return fmt.Sprintf("%v", ev.ResizeRequestEvent) +} + +type CirculateNotifyEvent struct { + *xproto.CirculateNotifyEvent +} + +const CirculateNotify = xproto.CirculateNotify + +func (ev CirculateNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.CirculateNotifyEvent) +} + +type CirculateRequestEvent struct { + *xproto.CirculateRequestEvent +} + +const CirculateRequest = xproto.CirculateRequest + +func (ev CirculateRequestEvent) String() string { + return fmt.Sprintf("%v", ev.CirculateRequestEvent) +} + +type PropertyNotifyEvent struct { + *xproto.PropertyNotifyEvent +} + +const PropertyNotify = xproto.PropertyNotify + +func (ev PropertyNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.PropertyNotifyEvent) +} + +type SelectionClearEvent struct { + *xproto.SelectionClearEvent +} + +const SelectionClear = xproto.SelectionClear + +func (ev SelectionClearEvent) String() string { + return fmt.Sprintf("%v", ev.SelectionClearEvent) +} + +type SelectionRequestEvent struct { + *xproto.SelectionRequestEvent +} + +const SelectionRequest = xproto.SelectionRequest + +func (ev SelectionRequestEvent) String() string { + return fmt.Sprintf("%v", ev.SelectionRequestEvent) +} + +type SelectionNotifyEvent struct { + *xproto.SelectionNotifyEvent +} + +const SelectionNotify = xproto.SelectionNotify + +func (ev SelectionNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.SelectionNotifyEvent) +} + +type ColormapNotifyEvent struct { + *xproto.ColormapNotifyEvent +} + +const ColormapNotify = xproto.ColormapNotify + +func (ev ColormapNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.ColormapNotifyEvent) +} + +type MappingNotifyEvent struct { + *xproto.MappingNotifyEvent +} + +const MappingNotify = xproto.MappingNotify + +func (ev MappingNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.MappingNotifyEvent) +} + +type ShapeNotifyEvent struct { + *shape.NotifyEvent +} + +const ShapeNotify = shape.Notify + +func (ev ShapeNotifyEvent) String() string { + return fmt.Sprintf("%v", ev.NotifyEvent) +} diff --git a/vend/xgbutil/xevent/types_manual.go b/vend/xgbutil/xevent/types_manual.go new file mode 100644 index 0000000..b005c6f --- /dev/null +++ b/vend/xgbutil/xevent/types_manual.go @@ -0,0 +1,90 @@ +package xevent + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" +) + +// ClientMessageEvent embeds the struct by the same name from the xgb library. +type ClientMessageEvent struct { + *xproto.ClientMessageEvent +} + +const ClientMessage = xproto.ClientMessage + +// NewClientMessage takes all arguments required to build a ClientMessageEvent +// struct and hides the messy details. +// The variadic parameters coincide with the "data" part of a client message. +// The type of the variadic parameters depends upon the value of Format. +// If Format is 8, 'data' should have type byte. +// If Format is 16, 'data' should have type int16. +// If Format is 32, 'data' should have type int. +// Any other value of Format returns an error. +func NewClientMessage(Format byte, Window xproto.Window, Type xproto.Atom, + data ...interface{}) (*ClientMessageEvent, error) { + + // Create the client data list first + var clientData xproto.ClientMessageDataUnion + + // Don't support formats 8 or 16 yet. They aren't used in EWMH anyway. + switch Format { + case 8: + buf := make([]byte, 20) + for i := 0; i < 20; i++ { + if i >= len(data) { + break + } + buf[i] = data[i].(byte) + } + clientData = xproto.ClientMessageDataUnionData8New(buf) + case 16: + buf := make([]uint16, 10) + for i := 0; i < 10; i++ { + if i >= len(data) { + break + } + buf[i] = uint16(data[i].(int16)) + } + clientData = xproto.ClientMessageDataUnionData16New(buf) + case 32: + buf := make([]uint32, 5) + for i := 0; i < 5; i++ { + if i >= len(data) { + break + } + buf[i] = uint32(data[i].(int)) + } + clientData = xproto.ClientMessageDataUnionData32New(buf) + default: + return nil, fmt.Errorf("NewClientMessage: Unsupported format '%d'.", + Format) + } + + return &ClientMessageEvent{&xproto.ClientMessageEvent{ + Format: Format, + Window: Window, + Type: Type, + Data: clientData, + }}, nil +} + +// ConfigureNotifyEvent embeds the struct by the same name in XGB. +type ConfigureNotifyEvent struct { + *xproto.ConfigureNotifyEvent +} + +const ConfigureNotify = xproto.ConfigureNotify + +// NewConfigureNotify takes all arguments required to build a +// ConfigureNotifyEvent struct and returns a ConfigureNotifyEvent value. +func NewConfigureNotify(Event, Window, AboveSibling xproto.Window, + X, Y, Width, Height int, BorderWidth uint16, + OverrideRedirect bool) *ConfigureNotifyEvent { + + return &ConfigureNotifyEvent{&xproto.ConfigureNotifyEvent{ + Event: Event, Window: Window, AboveSibling: AboveSibling, + X: int16(X), Y: int16(Y), Width: uint16(Width), Height: uint16(Height), + BorderWidth: BorderWidth, OverrideRedirect: OverrideRedirect, + }} +} diff --git a/vend/xgbutil/xevent/xevent.go b/vend/xgbutil/xevent/xevent.go new file mode 100644 index 0000000..2b3e83e --- /dev/null +++ b/vend/xgbutil/xevent/xevent.go @@ -0,0 +1,237 @@ +package xevent + +import ( + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// Sometimes we need to specify NO WINDOW when a window is typically +// expected. (Like connecting to MappingNotify or KeymapNotify events.) +// Use this value to do that. +var NoWindow xproto.Window = 0 + +// IgnoreMods is a list of X modifiers that we don't want interfering +// with our mouse or key bindings. In particular, for each mouse or key binding +// issued, there is a seperate mouse or key binding made for each of the +// modifiers specified. +// +// You may modify this slice to add (or remove) modifiers, but it should be +// done before *any* key or mouse bindings are attached with the keybind and +// mousebind packages. It should not be modified afterwards. +// +// TODO: We're assuming numlock is in the 'mod2' modifier, which is a pretty +// common setup, but by no means guaranteed. This should be modified to actually +// inspect the modifiers table and look for the special Num_Lock keysym. +var IgnoreMods []uint16 = []uint16{ + 0, + xproto.ModMaskLock, // Caps lock + xproto.ModMask2, // Num lock + xproto.ModMaskLock | xproto.ModMask2, // Caps and Num lock +} + +// Enqueue queues up an event read from X. +// Note that an event read may return an error, in which case, this queue +// entry will be an error and not an event. +// +// ev, err := XUtilValue.Conn().WaitForEvent() +// xevent.Enqueue(XUtilValue, ev, err) +// +// You probably shouldn't have to enqueue events yourself. This is done +// automatically if you're using xevent.Main{Ping} and/or xevent.Read. +func Enqueue(xu *xgbutil.XUtil, ev xgb.Event, err xgb.Error) { + xu.EvqueueLck.Lock() + defer xu.EvqueueLck.Unlock() + + xu.Evqueue = append(xu.Evqueue, xgbutil.EventOrError{ + Event: ev, + Err: err, + }) +} + +// Dequeue pops an event/error from the queue and returns it. +// The queue item is unwrapped and returned as multiple return values. +// Only one of the return values can be nil. +func Dequeue(xu *xgbutil.XUtil) (xgb.Event, xgb.Error) { + xu.EvqueueLck.Lock() + defer xu.EvqueueLck.Unlock() + + everr := xu.Evqueue[0] + xu.Evqueue = xu.Evqueue[1:] + return everr.Event, everr.Err +} + +// DequeueAt removes a particular item from the queue. +// This is primarily useful when attempting to compress events. +func DequeueAt(xu *xgbutil.XUtil, i int) { + xu.EvqueueLck.Lock() + defer xu.EvqueueLck.Unlock() + + xu.Evqueue = append(xu.Evqueue[:i], xu.Evqueue[i+1:]...) +} + +// Empty returns whether the event queue is empty or not. +func Empty(xu *xgbutil.XUtil) bool { + xu.EvqueueLck.RLock() + defer xu.EvqueueLck.RUnlock() + + return len(xu.Evqueue) == 0 +} + +// Peek returns a *copy* of the current queue so we can examine it. +// This can be useful when trying to determine if a particular kind of +// event will be processed in the future. +func Peek(xu *xgbutil.XUtil) []xgbutil.EventOrError { + xu.EvqueueLck.RLock() + defer xu.EvqueueLck.RUnlock() + + cpy := make([]xgbutil.EventOrError, len(xu.Evqueue)) + copy(cpy, xu.Evqueue) + return cpy +} + +// ErrorHandlerSet sets the default error handler for errors that come +// into the main event loop. (This may be removed in the future in favor +// of a particular callback interface like events, but these sorts of errors +// aren't handled often in practice, so maybe not.) +// This is only called for errors returned from unchecked (asynchronous error +// handling) requests. +// The default error handler just emits them to stderr. +func ErrorHandlerSet(xu *xgbutil.XUtil, fun xgbutil.ErrorHandlerFun) { + xu.ErrorHandler = fun +} + +// ErrorHandlerGet retrieves the default error handler. +func ErrorHandlerGet(xu *xgbutil.XUtil) xgbutil.ErrorHandlerFun { + return xu.ErrorHandler +} + +type HookFun func(xu *xgbutil.XUtil, event interface{}) bool + +func (callback HookFun) Connect(xu *xgbutil.XUtil) { + xu.HooksLck.Lock() + defer xu.HooksLck.Unlock() + + // COW + newHooks := make([]xgbutil.CallbackHook, len(xu.Hooks)) + copy(newHooks, xu.Hooks) + newHooks = append(newHooks, callback) + + xu.Hooks = newHooks +} + +func (callback HookFun) Run(xu *xgbutil.XUtil, event interface{}) bool { + return callback(xu, event) +} + +func getHooks(xu *xgbutil.XUtil) []xgbutil.CallbackHook { + xu.HooksLck.RLock() + defer xu.HooksLck.RUnlock() + + return xu.Hooks +} + +// RedirectKeyEvents, when set to a window id (greater than 0), will force +// *all* Key{Press,Release} to callbacks attached to the specified window. +// This is close to emulating a Keyboard grab without the racing. +// To stop redirecting key events, use window identifier '0'. +func RedirectKeyEvents(xu *xgbutil.XUtil, wid xproto.Window) { + xu.KeyRedirect = wid +} + +// RedirectKeyGet gets the window that key events are being redirected to. +// If 0, then no redirection occurs. +func RedirectKeyGet(xu *xgbutil.XUtil) xproto.Window { + return xu.KeyRedirect +} + +// Quit elegantly exits out of the main event loop. +// "Elegantly" in this case means that it finishes processing the current +// event, and breaks out of the loop afterwards. +// There is no particular reason to use this instead of something like os.Exit +// other than you might have code to run after the main event loop exits to +// "clean up." +func Quit(xu *xgbutil.XUtil) { + xu.Quit = true +} + +// Quitting returns whether it's time to quit. +// This is only used in the main event loop in xevent. +func Quitting(xu *xgbutil.XUtil) bool { + return xu.Quit +} + +// attachCallback associates a (event, window) tuple with an event. +// Use copy on write since we run callbacks *a lot* more than attaching them. +// (The copy on write only applies to the slice of callbacks rather than +// the map itself, since the initial allocation is guaranteed to come before +// any use of it.) +func attachCallback(xu *xgbutil.XUtil, evtype int, win xproto.Window, + fun xgbutil.Callback) { + + xu.CallbacksLck.Lock() + defer xu.CallbacksLck.Unlock() + + if _, ok := xu.Callbacks[evtype]; !ok { + xu.Callbacks[evtype] = make(map[xproto.Window][]xgbutil.Callback, 20) + } + if _, ok := xu.Callbacks[evtype][win]; !ok { + xu.Callbacks[evtype][win] = make([]xgbutil.Callback, 0) + } + + // COW + newCallbacks := make([]xgbutil.Callback, len(xu.Callbacks[evtype][win])) + copy(newCallbacks, xu.Callbacks[evtype][win]) + newCallbacks = append(newCallbacks, fun) + xu.Callbacks[evtype][win] = newCallbacks +} + +// runCallbacks executes every callback corresponding to a +// particular event/window tuple. +func runCallbacks(xu *xgbutil.XUtil, event interface{}, evtype int, + win xproto.Window) { + + // The callback slice for a particular (event type, window) tuple uses + // copy on write. So just take a pointer to whatever is there and use that. + // We can be sure that the slice won't change from underneathe us. + xu.CallbacksLck.RLock() + cbs := xu.Callbacks[evtype][win] + xu.CallbacksLck.RUnlock() + + for _, cb := range cbs { + cb.Run(xu, event) + } +} + +// Detach removes all callbacks associated with a particular window. +// Note that if you're also using the keybind and mousebind packages, a complete +// detachment should look like: +// +// keybind.Detach(XUtilValue, window-id) +// mousebind.Detach(XUtilValue, window-id) +// xevent.Detach(XUtilValue, window-id) +// +// If a window is no longer receiving events, these methods should be called. +// Otherwise, the memory used to store the handler info for that window will +// never be released. +func Detach(xu *xgbutil.XUtil, win xproto.Window) { + xu.CallbacksLck.Lock() + defer xu.CallbacksLck.Unlock() + + for evtype, _ := range xu.Callbacks { + delete(xu.Callbacks[evtype], win) + } +} + +// SendRootEvent takes a type implementing the xgb.Event interface, converts it +// to raw X bytes, and sends it to the root window using the SendEvent request. +func SendRootEvent(xu *xgbutil.XUtil, ev xgb.Event, evMask uint32) error { + return xproto.SendEventChecked(xu.Conn(), false, xu.RootWin(), evMask, + string(ev.Bytes())).Check() +} + +// ReplayPointer is a quick alias to AllowEvents with 'ReplayPointer' mode. +func ReplayPointer(xu *xgbutil.XUtil) { + xproto.AllowEvents(xu.Conn(), xproto.AllowReplayPointer, 0) +} diff --git a/vend/xgbutil/xgbutil.go b/vend/xgbutil/xgbutil.go new file mode 100644 index 0000000..6bfe637 --- /dev/null +++ b/vend/xgbutil/xgbutil.go @@ -0,0 +1,348 @@ +package xgbutil + +import ( + "log" + "os" + "sync" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xinerama" + "github.com/jezek/xgb/xproto" +) + +// Logger is used through xgbutil when messages need to be emitted to stderr. +var Logger = log.New(os.Stderr, "[xgbutil] ", log.Lshortfile) + +// The current maximum request size. I think we can expand this with +// BigReq, but it probably isn't worth it at the moment. +const MaxReqSize = (1 << 16) * 4 + +// An XUtil represents the state of xgbutil. It keeps track of the current +// X connection, the root window, event callbacks, key/mouse bindings, etc. +// Regrettably, many of the members are exported, even though they should not +// be used directly by the user. They are exported for use in sub-packages. +// (Namely, xevent, keybind and mousebind.) In fact, there should *never* +// be a reason to access any members of an XUtil value directly. Any +// interaction with an XUtil value should be through its methods. +type XUtil struct { + // conn is the XGB connection object used to issue protocol requests. + conn *xgb.Conn + + // Quit can be set to true, and the main event loop will finish processing + // the current event, and gracefully quit afterwards. + // This is exported for use in the xevent package. Please us xevent.Quit + // to set this value. + Quit bool // when true, the main event loop will stop gracefully + + // setup contains all the setup information retrieved at connection time. + setup *xproto.SetupInfo + + // screen is a simple alias to the default screen info. + screen *xproto.ScreenInfo + + // root is an alias to the default root window. + root xproto.Window + + // Atoms is a cache of atom names to resource identifiers. This minimizes + // round trips to the X server, since atom identifiers never change. + // It is exported for use in the xprop package. It should not be used. + Atoms map[string]xproto.Atom + AtomsLck *sync.RWMutex + + // AtomNames is a cache just like 'atoms', but in the reverse direction. + // It is exported for use in the xprop package. It should not be used. + AtomNames map[xproto.Atom]string + AtomNamesLck *sync.RWMutex + + // Evqueue is the queue that stores the results of xgb.WaitForEvent. + // Namely, each value is either an Event *or* an Error. + // It is exported for use in the xevent package. Do not use it. + // If you need to interact with the event queue, please use the functions + // available in the xevent package: Dequeue, DequeueAt, QueueEmpty + // and QueuePeek. + Evqueue []EventOrError + EvqueueLck *sync.RWMutex + + // Callbacks is a map of event numbers to a map of window identifiers + // to callback functions. + // This is the data structure that stores all callback functions, where + // a callback function is always attached to a (event, window) tuple. + // It is exported for use in the xevent package. Do not use it. + Callbacks map[int]map[xproto.Window][]Callback + CallbacksLck *sync.RWMutex + + // Hooks are called by the XEvent main loop before processing the event + // itself. These are meant for instances when it's not possible / easy + // to use the normal Hook system. You should not modify this yourself. + Hooks []CallbackHook + HooksLck *sync.RWMutex + + // eventTime is the last time recorded by an event. It is automatically + // updated if xgbutil's main event loop is used. + eventTime xproto.Timestamp + + // Keymap corresponds to xgbutil's current conception of the keyboard + // mapping. It is automatically kept up-to-date if xgbutil's event loop + // is used. + // It is exported for use in the keybind package. It should not be + // accessed directly. Instead, use keybind.KeyMapGet. + Keymap *KeyboardMapping + + // Modmap corresponds to xgbutil's current conception of the modifier key + // mapping. It is automatically kept up-to-date if xgbutil's event loop + // is used. + // It is exported for use in the keybind package. It should not be + // accessed directly. Instead, use keybind.ModMapGet. + Modmap *ModifierMapping + + // KeyRedirect corresponds to a window identifier that, when set, + // automatically receives *all* keyboard events. This is a sort-of + // synthetic grab and is helpful in avoiding race conditions. + // It is exported for use in the xevent and keybind packages. Do not use + // it directly. To redirect key events, please use xevent.RedirectKeyEvents. + KeyRedirect xproto.Window + + // Keybinds is the data structure storing all callbacks for key bindings. + // This is extremely similar to the general notion of event callbacks, + // but adds extra support to make handling key bindings easier. (Like + // specifying human readable key sequences to bind to.) + // KeyBindKey is a struct representing the 4-tuple + // (event-type, window-id, modifiers, keycode). + // It is exported for use in the keybind package. Do not access it directly. + Keybinds map[KeyKey][]CallbackKey + KeybindsLck *sync.RWMutex + + // Keygrabs is a frequency count of the number of callbacks associated + // with a particular KeyBindKey. This is necessary because we can only + // grab a particular key *once*, but we may want to attach several callbacks + // to a single keypress. + // It is exported for use in the keybind package. Do not access it directly. + Keygrabs map[KeyKey]int + + // Keystrings is a list of all key strings used to connect keybindings. + // They are used to rebuild key grabs when the keyboard mapping is updated. + // It is exported for use in the keybind package. Do not access it directly. + Keystrings []KeyString + + // Mousebinds is the data structure storing all callbacks for mouse + // bindings.This is extremely similar to the general notion of event + // callbacks,but adds extra support to make handling mouse bindings easier. + // (Like specifying human readable mouse sequences to bind to.) + // MouseBindKey is a struct representing the 4-tuple + // (event-type, window-id, modifiers, button). + // It is exported for use in the mousebind package. Do not use it. + Mousebinds map[MouseKey][]CallbackMouse + MousebindsLck *sync.RWMutex + + // Mousegrabs is a frequency count of the number of callbacks associated + // with a particular MouseBindKey. This is necessary because we can only + // grab a particular mouse button *once*, but we may want to attach + // several callbacks to a single button press. + // It is exported for use in the mousebind package. Do not use it. + Mousegrabs map[MouseKey]int + + // InMouseDrag is true if a drag is currently in progress. + // It is exported for use in the mousebind package. Do not use it. + InMouseDrag bool + + // MouseDragStep is the function executed for each step (i.e., pointer + // movement) in the current mouse drag. Note that this is nil when a drag + // is not in progress. + // It is exported for use in the mousebind package. Do not use it. + MouseDragStepFun MouseDragFun + + // MouseDragEnd is the function executed at the end of the current + // mouse drag. This is nil when a drag is not in progress. + // It is exported for use in the mousebind package. Do not use it. + MouseDragEndFun MouseDragFun + + // gc is a general purpose graphics context; used to paint images. + // Since we don't do any real X drawing, we don't really care about the + // particulars of our graphics context. + gc xproto.Gcontext + + // dummy is a dummy window used for mouse/key GRABs. + // Basically, whenever a grab is instituted, mouse and key events are + // redirected to the dummy the window. + dummy xproto.Window + + // ErrorHandler is the function that handles errors *in the event loop*. + // By default, it simply emits them to stderr. + // It is exported for use in the xevent package. To set the default error + // handler, please use xevent.ErrorHandlerSet. + ErrorHandler ErrorHandlerFun +} + +// NewConn connects to the X server using the DISPLAY environment variable +// and creates a new XUtil. Most environments have the DISPLAY environment +// variable set, so this is probably what you want to use to connect to X. +func NewConn() (*XUtil, error) { + return NewConnDisplay("") +} + +// NewConnDisplay connects to the X server and creates a new XUtil. +// If 'display' is empty, the DISPLAY environment variable is used. Otherwise +// there are several different display formats supported: +// +// NewConn(":1") -> net.Dial("unix", "", "/tmp/.X11-unix/X1") +// NewConn("/tmp/launch-12/:0") -> net.Dial("unix", "", "/tmp/launch-12/:0") +// NewConn("hostname:2.1") -> net.Dial("tcp", "", "hostname:6002") +// NewConn("tcp/hostname:1.0") -> net.Dial("tcp", "", "hostname:6001") +func NewConnDisplay(display string) (*XUtil, error) { + c, err := xgb.NewConnDisplay(display) + + if err != nil { + return nil, err + } + + return NewConnXgb(c) + +} + +// NewConnXgb use the specific xgb.Conn to create a new XUtil. +// +// NewConn, NewConnDisplay are wrapper of this function. +func NewConnXgb(c *xgb.Conn) (*XUtil, error) { + setup := xproto.Setup(c) + screen := setup.DefaultScreen(c) + + // Initialize our central struct that stores everything. + xu := &XUtil{ + conn: c, + Quit: false, + Evqueue: make([]EventOrError, 0, 1000), + EvqueueLck: &sync.RWMutex{}, + setup: setup, + screen: screen, + root: screen.Root, + eventTime: xproto.Timestamp(0), // last event time + Atoms: make(map[string]xproto.Atom, 50), + AtomsLck: &sync.RWMutex{}, + AtomNames: make(map[xproto.Atom]string, 50), + AtomNamesLck: &sync.RWMutex{}, + Callbacks: make(map[int]map[xproto.Window][]Callback, 33), + CallbacksLck: &sync.RWMutex{}, + Hooks: make([]CallbackHook, 0), + HooksLck: &sync.RWMutex{}, + Keymap: nil, // we don't have anything yet + Modmap: nil, + KeyRedirect: 0, + Keybinds: make(map[KeyKey][]CallbackKey, 10), + KeybindsLck: &sync.RWMutex{}, + Keygrabs: make(map[KeyKey]int, 10), + Keystrings: make([]KeyString, 0, 10), + Mousebinds: make(map[MouseKey][]CallbackMouse, 10), + MousebindsLck: &sync.RWMutex{}, + Mousegrabs: make(map[MouseKey]int, 10), + InMouseDrag: false, + MouseDragStepFun: nil, + MouseDragEndFun: nil, + ErrorHandler: func(err xgb.Error) { Logger.Println(err) }, + } + + var err error = nil + // Create a general purpose graphics context + xu.gc, err = xproto.NewGcontextId(xu.conn) + if err != nil { + return nil, err + } + xproto.CreateGC(xu.conn, xu.gc, xproto.Drawable(xu.root), + xproto.GcForeground, []uint32{xu.screen.WhitePixel}) + + // Create a dummy window + xu.dummy, err = xproto.NewWindowId(xu.conn) + if err != nil { + return nil, err + } + xproto.CreateWindow(xu.conn, xu.Screen().RootDepth, xu.dummy, xu.RootWin(), + -1000, -1000, 1, 1, 0, + xproto.WindowClassInputOutput, xu.Screen().RootVisual, + xproto.CwEventMask|xproto.CwOverrideRedirect, + []uint32{1, xproto.EventMaskPropertyChange}) + xproto.MapWindow(xu.conn, xu.dummy) + + // Register the Xinerama extension... because it doesn't cost much. + err = xinerama.Init(xu.conn) + + // If we can't register Xinerama, that's okay. Output something + // and move on. + if err != nil { + Logger.Printf("WARNING: %s\n", err) + Logger.Printf("MESSAGE: The 'xinerama' package cannot be used " + + "because the XINERAMA extension could not be loaded.") + } + + return xu, nil +} + +// Conn returns the xgb connection object. +func (xu *XUtil) Conn() *xgb.Conn { + return xu.conn +} + +// ExtInitialized returns true if an extension has been initialized. +// This is useful for determining whether an extension is available or not. +func (xu *XUtil) ExtInitialized(extName string) bool { + _, ok := xu.Conn().Extensions[extName] + return ok +} + +// Sync forces XGB to catch up with all events/requests and synchronize. +// This is done by issuing a benign round trip request to X. +func (xu *XUtil) Sync() { + xproto.GetInputFocus(xu.Conn()).Reply() +} + +// Setup returns the setup information retrieved during connection time. +func (xu *XUtil) Setup() *xproto.SetupInfo { + return xu.setup +} + +// Screen returns the default screen +func (xu *XUtil) Screen() *xproto.ScreenInfo { + return xu.screen +} + +// RootWin returns the current root window. +func (xu *XUtil) RootWin() xproto.Window { + return xu.root +} + +// RootWinSet will change the current root window to the one provided. +// N.B. This probably shouldn't be used unless you're desperately trying +// to support multiple X screens. (This is *not* the same as Xinerama/RandR or +// TwinView. All of those have a single root window.) +func (xu *XUtil) RootWinSet(root xproto.Window) { + xu.root = root +} + +// TimeGet gets the most recent time seen by an event. +func (xu *XUtil) TimeGet() xproto.Timestamp { + return xu.eventTime +} + +// TimeSet sets the most recent time seen by an event. +func (xu *XUtil) TimeSet(t xproto.Timestamp) { + xu.eventTime = t +} + +// GC gets a general purpose graphics context that is typically used to simply +// paint images. +func (xu *XUtil) GC() xproto.Gcontext { + return xu.gc +} + +// Dummy gets the id of the dummy window. +func (xu *XUtil) Dummy() xproto.Window { + return xu.dummy +} + +// Grabs the server. Everything becomes synchronous. +func (xu *XUtil) Grab() { + xproto.GrabServer(xu.Conn()) +} + +// Ungrabs the server. +func (xu *XUtil) Ungrab() { + xproto.UngrabServer(xu.Conn()) +} diff --git a/vend/xgbutil/xgraphics/convert.go b/vend/xgbutil/xgraphics/convert.go new file mode 100644 index 0000000..e086a96 --- /dev/null +++ b/vend/xgbutil/xgraphics/convert.go @@ -0,0 +1,120 @@ +package xgraphics + +/* +A set of conversion functions for some image types defined in the Go standard +library. They can be up to 80% faster because the inner loop doesn't use +interfaces. Wow. + +Note that these functions assume that the source and destination are precisely +the same size. +*/ + +import ( + "image" + "image/color" +) + +// convertImage converts any image implementing the image.Image interface to +// an xgraphics.Image type. This is *slow*. +func convertImage(dest *Image, src image.Image) { + var r, g, b, a uint32 + var x, y, i int + + for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { + for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { + r, g, b, a = src.At(x, y).RGBA() + i = dest.PixOffset(x, y) + dest.Pix[i+0] = uint8(b >> 8) + dest.Pix[i+1] = uint8(g >> 8) + dest.Pix[i+2] = uint8(r >> 8) + dest.Pix[i+3] = uint8(a >> 8) + } + } +} + +func convertXImage(dest *Image, src *Image) { + copy(dest.Pix, src.Pix) +} + +func convertYCbCr(dest *Image, src *image.YCbCr) { + var r, g, b uint8 + var x, y, i, yi, ci int + + for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { + for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { + yi, ci = src.YOffset(x, y), src.COffset(x, y) + r, g, b = color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci]) + i = dest.PixOffset(x, y) + dest.Pix[i+0] = b + dest.Pix[i+1] = g + dest.Pix[i+2] = r + dest.Pix[i+3] = 0xff + } + } +} + +func convertRGBA(dest *Image, src *image.RGBA) { + var x, y, i, si int + + for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { + for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { + si = src.PixOffset(x, y) + i = dest.PixOffset(x, y) + dest.Pix[i+0] = src.Pix[si+2] + dest.Pix[i+1] = src.Pix[si+1] + dest.Pix[i+2] = src.Pix[si+0] + dest.Pix[i+3] = src.Pix[si+3] + } + } +} + +func convertRGBA64(dest *Image, src *image.RGBA64) { + var x, y, i, si int + + for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { + for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { + si = src.PixOffset(x, y) + i = dest.PixOffset(x, y) + dest.Pix[i+0] = src.Pix[si+4] + dest.Pix[i+1] = src.Pix[si+2] + dest.Pix[i+2] = src.Pix[si+0] + dest.Pix[i+3] = src.Pix[si+6] + } + } +} + +func convertNRGBA(dest *Image, src *image.NRGBA) { + var x, y, i, si int + var a uint16 + + for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { + for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { + si = src.PixOffset(x, y) + i = dest.PixOffset(x, y) + a = uint16(src.Pix[si+3]) + + dest.Pix[i+0] = uint8((uint16(src.Pix[si+2]) * a) / 0xff) + dest.Pix[i+1] = uint8((uint16(src.Pix[si+1]) * a) / 0xff) + dest.Pix[i+2] = uint8((uint16(src.Pix[si+0]) * a) / 0xff) + dest.Pix[i+3] = src.Pix[si+3] + } + } +} + +func convertNRGBA64(dest *Image, src *image.NRGBA64) { + var x, y, i, si int + var a uint16 + + for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { + for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { + si = src.PixOffset(x, y) + i = dest.PixOffset(x, y) + a = uint16(src.Pix[si+6]) + + dest.Pix[i+0] = uint8((uint16(src.Pix[si+4]) * a) / 0xff) + dest.Pix[i+1] = uint8((uint16(src.Pix[si+2]) * a) / 0xff) + dest.Pix[i+2] = uint8((uint16(src.Pix[si+0]) * a) / 0xff) + dest.Pix[i+3] = src.Pix[si+6] + } + } +} diff --git a/vend/xgbutil/xgraphics/doc.go b/vend/xgbutil/xgraphics/doc.go new file mode 100644 index 0000000..f9afc7f --- /dev/null +++ b/vend/xgbutil/xgraphics/doc.go @@ -0,0 +1,90 @@ +/* +Package xgraphics defines an X image type and provides convenience functions +for reading and writing X pixmaps and bitmaps. It is a work-in-progress, and +while it works for some common X server configurations, it does not work for +all X server configurations. Package xgraphics also provides some support for +drawing text on to images using freetype-go, scaling images using graphics-go, +simple alpha blending, finding EWMH and ICCCM window icons and efficiently +drawing any image into an X pixmap. (Where "efficient" means being able to +specify sub-regions of images to draw, so that the entire image isn't sent to +X.) If more elaborate image routines are required, I recommend using draw2d. +(The xgraphics.Image type satisfies the draw.Image interface, which allows it +to work with draw2d.) + +In general, xgraphics paints pixmaps to windows using using the BackPixmap +approach. (Setting the background pixmap of the window to the pixmap containing +your image, and clearing the window's background when the pixmap is updated.) +It also provides experimental support for another mechanism: copying the +contents of your image's pixmap directly to the window. (This requires +responding to expose events to redraw the pixmap.) The former approach requires +less book-keeping, but supposedly has some issues with some video cards. The +latter approach is probably more reliable, but requires more book-keeping. + +Note that while text drawing functions are provided, it is not necessary to use +them to write text on images. Namely, there is nothing X specific about them. +They are strictly for convenience. + +A quick example + +This is a simple example the converts any value satisfying the image.Image +interface into an *xgraphics.Image value, and creates a new window with that +image painted in the window. (The XShow function probably doesn't have any +practical applications outside serving as an example, but can be useful for +debugging what an image looks like.) + + imgFile, err := os.Open(imgPath) + if err != nil { + log.Fatal(err) + } + + img, _, err := image.Decode(imgFile) + if err != nil { + log.Fatal(err) + } + + ximg := xgraphics.NewConvert(XUtilValue, img) + ximg.XShow() + +A complete working example named 'show-image' that's similar to this can be +found in the examples directory of the xgbutil package. More involved examples, +'show-window-icons' and 'pointer-painting', are also provided. + +Portability + +The xgraphics package *assumes* a particular kind of X server configuration. +Namely, this configuration specifies bits per pixel, image byte order, bitmap +bit order, scanline padding and unit length, image depth and so on. Handling +all of the possible values for each configuration option will greatly inflate +the code, but is on the TODO list. + +I am (BurntSushi) undecided (perhaps because I haven't thought about it too much) about +whether to hide these configuration details behind multiple xgraphics.Image +types or hiding everything inside one xgraphics.Image type. I lean toward the +latter because the former requires a large number of types (and therefore a lot +of code duplication). One design decision that I've already made is that images +should be converted to the format used by the X server (xgraphics currently +assumes this is BGRx) once when the image is created. Without this, an +xgraphics.Image type wouldn't be required, and images would have to be +converted to the X image format every time an image is drawn into a pixmap. +This results in a lot of overhead. Moreover, Go's interfaces allow an +xgraphics.Image type to work anywhere that an image.Image or a draw.Image value +is expected. + +The obvious down-side to this approach is that optimizations made in image +drawing routines in other libraries won't be able to apply to xgraphics.Image +values (since the optimizations are probably hard-coded for image types +declared in Go's standard library). This isn't well suited to the process of +creating some canvas to draw on, and using another library to draw on the +canvas. (At least, it won't be as fast as possible.) I can't think of any way +around this, other than having the library add an optimization step +specifically for xgraphics.Image values. Of course, the other approach is to +convert image formats only when drawing to X and completely subvert the +xgraphics.Image type, but this seems worse than unoptimized image drawing +routines. (Unfortunately, both things need to be fast.) + +If your X server is not configured to what the xgraphics package expects, +messages will be emitted to stderr when a new xgraphics.Image value is created. +If you see any of these messages, please report them to xgbutil's project page: +https://github.com/jezek/xgbutil. +*/ +package xgraphics diff --git a/vend/xgbutil/xgraphics/image.go b/vend/xgbutil/xgraphics/image.go new file mode 100644 index 0000000..1ee0f2f --- /dev/null +++ b/vend/xgbutil/xgraphics/image.go @@ -0,0 +1,299 @@ +package xgraphics + +/* +xgraphics/image.go contains an implementation of the draw.Image interface. + +RGBA could feasibly be used, but the representation of image data is dependent +upon the configuration of the X server. + +For the time being, I'm hard-coding a lot of that configuration for the common +case. Namely: + +Byte order: least significant byte first +Depth: 24 +Bits per pixel: 32 + +This will have to be fixed for this to be truly compatible with any X server. + +Most of the code is based heavily on the implementation of common images in +the Go standard library. + +Manipulating images isn't something I've had much experience with, so if it +seems like I'm doing something stupid, I probably am. +*/ + +import ( + "image" + "image/color" + "image/png" + "io" + "os" + + "github.com/BurntSushi/graphics-go/graphics" + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xwindow" +) + +// Model for the BGRA color type. +var BGRAModel color.Model = color.ModelFunc(bgraModel) + +type Image struct { + // X images must be tied to an X connection. + X *xgbutil.XUtil + + // X images must also be tied to a pixmap (its drawing surface). + // Calls to 'XDraw' will draw data to this pixmap. + // Calls to 'XPaint' will tell X to show the pixmap on some window. + Pixmap xproto.Pixmap + + // Pix holds the image's pixels in BGRA order, so that they don't need + // to be swapped for every PutImage request. + Pix []uint8 + + // Stride corresponds to the number of elements in Pix between two pixels + // that are vertically adjacent. + Stride int + + // The geometry of the image. + Rect image.Rectangle + + // Whether this is a sub-image or not. + // This is useful to know when sending data or setting surfaces. + // Namely, sub-images cannot be set as surfaces and sub-images, when + // being drawn, only have its pixels sent to X instead of the whole image. + Subimg bool +} + +// New returns a new instance of Image with colors initialized to black +// for the geometry given. +// New will also create an X pixmap. When you are no longer using this +// image, you should call Destroy so that the X pixmap can be freed on the +// X server. +// If 'X' is nil, then a new connection will be made. This is usually a bad +// idea, particularly if you're making a lot of small images, but can be +// used to achieve true parallelism. (Particularly useful when painting large +// images.) +func New(X *xgbutil.XUtil, r image.Rectangle) *Image { + var err error + if X == nil { + X, err = xgbutil.NewConn() + if err != nil { + xgbutil.Logger.Panicf("Could not create a new connection when "+ + "creating a new xgraphics.Image value because: %s", err) + } + } + + return &Image{ + X: X, + Pixmap: 0, + Pix: make([]uint8, 4*r.Dx()*r.Dy()), + Stride: 4 * r.Dx(), + Rect: r, + Subimg: false, + } +} + +// Destroy frees the pixmap resource being used by this image. +// It should be called whenever the image will no longer be drawn or painted. +func (im *Image) Destroy() { + if im.Pixmap != 0 { + xproto.FreePixmap(im.X.Conn(), im.Pixmap) + im.Pixmap = 0 + } +} + +// Scale will scale the image to the size provided. +// Note that this will destroy the current pixmap associated with this image. +// After scaling, XSurfaceSet will need to be called for each window that +// this image is painted to. (And obviously, XDraw and XPaint will need to +// be called again.) +func (im *Image) Scale(width, height int) *Image { + dimg := New(im.X, image.Rect(0, 0, width, height)) + graphics.Scale(dimg, im) + im.Destroy() + + return dimg +} + +// WritePng encodes the image to w as a png. +func (im *Image) WritePng(w io.Writer) error { + return png.Encode(w, im) +} + +// SavePng writes the Image to a file with name as a png. +func (im *Image) SavePng(name string) error { + file, err := os.Create(name) + if err != nil { + return err + } + return im.WritePng(file) +} + +// ColorModel returns the color.Model used by the Image struct. +func (im *Image) ColorModel() color.Model { + return BGRAModel +} + +// Bounds returns the rectangle representing the geometry of Image. +func (im *Image) Bounds() image.Rectangle { + return im.Rect +} + +// At returns the color at the specified pixel. +func (im *Image) At(x, y int) color.Color { + if !(image.Point{x, y}.In(im.Rect)) { + return BGRA{} + } + i := im.PixOffset(x, y) + return BGRA{ + B: im.Pix[i], + G: im.Pix[i+1], + R: im.Pix[i+2], + A: im.Pix[i+3], + } +} + +// Set satisfies the draw.Image interface by allowing the color of a pixel +// at (x, y) to be changed. +func (im *Image) Set(x, y int, c color.Color) { + if !(image.Point{x, y}.In(im.Rect)) { + return + } + + i := im.PixOffset(x, y) + cc := BGRAModel.Convert(c).(BGRA) + im.Pix[i] = cc.B + im.Pix[i+1] = cc.G + im.Pix[i+2] = cc.R + im.Pix[i+3] = cc.A +} + +// SetBGRA is like set, but without the type assertion. +func (im *Image) SetBGRA(x, y int, c BGRA) { + if !(image.Point{x, y}.In(im.Rect)) { + return + } + + i := im.PixOffset(x, y) + im.Pix[i] = c.B + im.Pix[i+1] = c.G + im.Pix[i+2] = c.R + im.Pix[i+3] = c.A +} + +// For transforms every pixel color to the color returned by 'each' given +// an (x, y) position. +func (im *Image) For(each func(x, y int) BGRA) { + for x := im.Rect.Min.X; x < im.Rect.Max.X; x++ { + for y := im.Rect.Min.Y; y < im.Rect.Max.Y; y++ { + im.SetBGRA(x, y, each(x, y)) + } + } +} + +// ForExp is like For, but bypasses image.Color types. +// (So it should be faster.) +func (im *Image) ForExp(each func(x, y int) (r, g, b, a uint8)) { + var x, y, i int + var r, g, b, a uint8 + for x = im.Rect.Min.X; x < im.Rect.Max.X; x++ { + for y = im.Rect.Min.Y; y < im.Rect.Max.Y; y++ { + i = im.PixOffset(x, y) + r, g, b, a = each(x, y) + + im.Pix[i+0] = b + im.Pix[i+1] = g + im.Pix[i+2] = r + im.Pix[i+3] = a + } + } +} + +// SubImage provides a sub image of Image without copying image data. +// N.B. The standard library defines a similar function, but returns an +// image.Image. Here, we return xgraphics.Image so that we can use the extra +// methods defined by xgraphics on it. +// +// This method is cheap to call. It should be used to update only specific +// regions of an X pixmap to avoid sending an entire image to the X server when +// only a piece of it is updated. +// +// Note that if the intersection of `r` and `im` is empty, `nil` is returned. +func (im *Image) SubImage(r image.Rectangle) image.Image { + r = r.Intersect(im.Rect) + if r.Empty() { + return nil + } + + i := im.PixOffset(r.Min.X, r.Min.Y) + return &Image{ + X: im.X, + Pixmap: im.Pixmap, + Pix: im.Pix[i:], + Stride: im.Stride, + Rect: r, + Subimg: true, + } +} + +// PixOffset returns the index of the frst element of the Pix data that +// corresponds to the pixel at (x, y). +func (im *Image) PixOffset(x, y int) int { + return (y-im.Rect.Min.Y)*im.Stride + (x-im.Rect.Min.X)*4 +} + +// Window is a convenience function for painting the provided +// Image value to a new window, destroying the pixmap created by that image, +// and returning the window value. +// The window is sized to the dimensions of the image. +func (im *Image) Window(parent xproto.Window) *xwindow.Window { + win := xwindow.Must(xwindow.Create(im.X, parent)) + win.Resize(im.Bounds().Dx(), im.Bounds().Dy()) + + im.XSurfaceSet(win.Id) + im.XDraw() + im.XPaint(win.Id) + im.Destroy() + + return win +} + +// BGRA is the representation of color for each pixel in an X pixmap. +// BUG(burntsushi): This is hard-coded when it shouldn't be. +type BGRA struct { + B, G, R, A uint8 +} + +// RGBA satisfies the color.Color interface. +func (c BGRA) RGBA() (r, g, b, a uint32) { + r = uint32(c.R) + r |= r << 8 + + g = uint32(c.G) + g |= g << 8 + + b = uint32(c.B) + b |= b << 8 + + a = uint32(c.A) + a |= a << 8 + + return +} + +// bgraModel converts from any color to a BGRA color type. +func bgraModel(c color.Color) color.Color { + if _, ok := c.(BGRA); ok { + return c + } + + r, g, b, a := c.RGBA() + return BGRA{ + B: uint8(b >> 8), + G: uint8(g >> 8), + R: uint8(r >> 8), + A: uint8(a >> 8), + } +} diff --git a/vend/xgbutil/xgraphics/new.go b/vend/xgbutil/xgraphics/new.go new file mode 100644 index 0000000..4d7977a --- /dev/null +++ b/vend/xgbutil/xgraphics/new.go @@ -0,0 +1,319 @@ +package xgraphics + +/* +xgraphics/new.go contains a few additional constructors for creating an +xgraphics.Image. +*/ + +import ( + "bytes" + "fmt" + "image" + _ "image/gif" + _ "image/jpeg" + _ "image/png" + "os" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/xwindow" +) + +// NewConvert converts any image satisfying the image.Image interface to an +// xgraphics.Image type. +// If 'img' is an xgraphics.Image, it will be copied and a new image will +// be returned. +// Also, NewConvert attempts to optimize image conversion for some image +// formats. (i.e., *image.RGBA.) +func NewConvert(X *xgbutil.XUtil, img image.Image) *Image { + ximg := New(X, img.Bounds()) + + // I've attempted to optimize this loop. + // It actually takes more time to convert an image than to send the bytes + // over the wire. (I suspect 'copy' is super fast, which can be used in + // XDraw, whereas computing each pixel is super slow.) + // But how is image decoding so much faster than this? I'll have to + // investigate... Maybe the Color interface being used here is the real + // slow down. + switch concrete := img.(type) { + case *image.NRGBA: + convertNRGBA(ximg, concrete) + case *image.NRGBA64: + convertNRGBA64(ximg, concrete) + case *image.RGBA: + convertRGBA(ximg, concrete) + case *image.RGBA64: + convertRGBA64(ximg, concrete) + case *image.YCbCr: + convertYCbCr(ximg, concrete) + case *Image: + convertXImage(ximg, concrete) + default: + xgbutil.Logger.Printf("Converting image type %T the slow way. "+ + "Optimization for this image type hasn't been added yet.", img) + convertImage(ximg, img) + } + return ximg +} + +// NewFileName uses the image package's decoder and converts a file specified +// by fileName to an xgraphics.Image value. +// Opening a file or decoding an image can cause an error. +func NewFileName(X *xgbutil.XUtil, fileName string) (*Image, error) { + srcReader, err := os.Open(fileName) + if err != nil { + return nil, err + } + defer srcReader.Close() + + img, _, err := image.Decode(srcReader) + if err != nil { + return nil, err + } + return NewConvert(X, img), nil +} + +// NewBytes uses the image package's decoder to convert the bytes given to +// an xgraphics.Imag value. +// Decoding an image can cause an error. +func NewBytes(X *xgbutil.XUtil, bs []byte) (*Image, error) { + img, _, err := image.Decode(bytes.NewReader(bs)) + if err != nil { + return nil, err + } + return NewConvert(X, img), nil +} + +// NewEwmhIcon converts EWMH icon data (ARGB) to an xgraphics.Image type. +// You should probably use xgraphics.FindIcon instead of this directly. +func NewEwmhIcon(X *xgbutil.XUtil, icon *ewmh.WmIcon) *Image { + ximg := New(X, image.Rect(0, 0, int(icon.Width), int(icon.Height))) + r := ximg.Rect + width := r.Dx() + + var argb, x, y int + for x = r.Min.X; x < r.Max.X; x++ { + for y = r.Min.Y; y < r.Max.Y; y++ { + argb = int(icon.Data[x+(y*width)]) + ximg.SetBGRA(x, y, BGRA{ + B: uint8(argb & 0x000000ff), + G: uint8((argb & 0x0000ff00) >> 8), + R: uint8((argb & 0x00ff0000) >> 16), + A: uint8(argb >> 24), + }) + } + } + return ximg +} + +// NewIcccmIcon converts two pixmap ids (icon_pixmap and icon_mask in the +// WM_HINTS properts) to a single xgraphics.Image. +// It is okay for one of iconPixmap or iconMask to be 0, but not both. +// You should probably use xgraphics.FindIcon instead of this directly. +func NewIcccmIcon(X *xgbutil.XUtil, iconPixmap, + iconMask xproto.Pixmap) (*Image, error) { + + if iconPixmap == 0 && iconMask == 0 { + return nil, fmt.Errorf("NewIcccmIcon: At least one of iconPixmap or " + + "iconMask must be non-zero, but both are 0.") + } + + var pximg, mximg *Image + var err error + + // Get the xgraphics.Image for iconPixmap. + if iconPixmap != 0 { + pximg, err = NewDrawable(X, xproto.Drawable(iconPixmap)) + if err != nil { + return nil, err + } + } + + // Now get the xgraphics.Image for iconMask. + if iconMask != 0 { + mximg, err = NewDrawable(X, xproto.Drawable(iconMask)) + if err != nil { + return nil, err + } + } + + // Now merge them together if both were specified. + switch { + case pximg != nil && mximg != nil: + r := pximg.Bounds() + + var x, y int + var bgra, maskBgra BGRA + for x = r.Min.X; x < r.Max.X; x++ { + for y = r.Min.Y; y < r.Max.Y; y++ { + maskBgra = mximg.At(x, y).(BGRA) + bgra = pximg.At(x, y).(BGRA) + if maskBgra.A == 0 { + pximg.SetBGRA(x, y, BGRA{ + B: bgra.B, + G: bgra.G, + R: bgra.R, + A: 0, + }) + } + } + } + return pximg, nil + case pximg != nil: + return pximg, nil + case mximg != nil: + return mximg, nil + } + + panic("unreachable") +} + +// NewDrawable converts an X drawable into a xgraphics.Image. +// This is used in NewIcccmIcon. +func NewDrawable(X *xgbutil.XUtil, did xproto.Drawable) (*Image, error) { + // Get the geometry of the pixmap for use in the GetImage request. + pgeom, err := xwindow.RawGeometry(X, xproto.Drawable(did)) + if err != nil { + return nil, err + } + + // Get the image data for each pixmap. + pixmapData, err := xproto.GetImage(X.Conn(), xproto.ImageFormatZPixmap, + did, + 0, 0, uint16(pgeom.Width()), uint16(pgeom.Height()), + (1<<32)-1).Reply() + if err != nil { + return nil, err + } + + // Now create the xgraphics.Image and populate it with data from + // pixmapData and maskData. + ximg := New(X, image.Rect(0, 0, pgeom.Width(), pgeom.Height())) + + // We'll try to be a little flexible with the image format returned, + // but not completely flexible. + err = readDrawableData(X, ximg, did, pixmapData, + pgeom.Width(), pgeom.Height()) + if err != nil { + return nil, err + } + + return ximg, nil +} + +// readDrawableData uses Format information to read data from an X pixmap +// into an xgraphics.Image. +// readPixmapData does not take into account all information possible to read +// X pixmaps and bitmaps. Of particular note is bit order/byte order. +func readDrawableData(X *xgbutil.XUtil, ximg *Image, did xproto.Drawable, + imgData *xproto.GetImageReply, width, height int) error { + + format := GetFormat(X, imgData.Depth) + if format == nil { + return fmt.Errorf("Could not find valid format for pixmap %d "+ + "with depth %d", did, imgData.Depth) + } + + switch format.Depth { + case 1: // We read bitmaps in as alpha masks. + if format.BitsPerPixel != 1 { + return fmt.Errorf("The image returned for pixmap id %d with "+ + "depth %d has an unsupported value for bits-per-pixel: %d", + did, format.Depth, format.BitsPerPixel) + } + + // Calculate the padded width of our image data. + pad := int(X.Setup().BitmapFormatScanlinePad) + paddedWidth := width + if width%pad != 0 { + paddedWidth = width + pad - (width % pad) + } + + // Process one scanline at a time. Each 'y' represents a + // single scanline. + for y := 0; y < height; y++ { + // Each scanline has length 'width' padded to + // BitmapFormatScanlinePad, which is found in the X setup info. + // 'i' is the index to the starting byte of the yth scanline. + i := y * paddedWidth / 8 + for x := 0; x < width; x++ { + b := imgData.Data[i+x/8] >> uint(x%8) + if b&1 > 0 { // opaque + ximg.Set(x, y, BGRA{0x0, 0x0, 0x0, 0xff}) + } else { // transparent + ximg.Set(x, y, BGRA{0xff, 0xff, 0xff, 0x0}) + } + } + } + case 24, 32: + switch format.BitsPerPixel { + case 24: + bytesPer := int(format.BitsPerPixel) / 8 + var i int + ximg.For(func(x, y int) BGRA { + i = y*width*bytesPer + x*bytesPer + return BGRA{ + B: imgData.Data[i], + G: imgData.Data[i+1], + R: imgData.Data[i+2], + A: 0xff, + } + }) + case 32: + bytesPer := int(format.BitsPerPixel) / 8 + var i int + ximg.For(func(x, y int) BGRA { + i = y*width*bytesPer + x*bytesPer + return BGRA{ + B: imgData.Data[i], + G: imgData.Data[i+1], + R: imgData.Data[i+2], + A: imgData.Data[i+3], + } + }) + default: + return fmt.Errorf("The image returned for pixmap id %d has "+ + "an unsupported value for bits-per-pixel: %d", + did, format.BitsPerPixel) + } + + default: + return fmt.Errorf("The image returned for pixmap id %d has an "+ + "unsupported value for depth: %d", did, format.Depth) + } + + return nil +} + +// GetFormat searches SetupInfo for a Format matching the depth provided. +func GetFormat(X *xgbutil.XUtil, depth byte) *xproto.Format { + for _, pixForm := range X.Setup().PixmapFormats { + if pixForm.Depth == depth { + return &pixForm + } + } + return nil +} + +// getVisualInfo searches SetupInfo for a VisualInfo value matching +// the depth provided. +// XXX: This isn't used (yet). +func getVisualInfo(X *xgbutil.XUtil, depth byte, + visualid xproto.Visualid) *xproto.VisualInfo { + + for _, depthInfo := range X.Screen().AllowedDepths { + fmt.Printf("%#v\n", depthInfo) + // fmt.Printf("%#v\n", depthInfo.Visuals) + fmt.Println("------------") + if depthInfo.Depth == depth { + for _, visual := range depthInfo.Visuals { + if visual.VisualId == visualid { + return &visual + } + } + } + } + return nil +} diff --git a/vend/xgbutil/xgraphics/text.go b/vend/xgbutil/xgraphics/text.go new file mode 100644 index 0000000..026426a --- /dev/null +++ b/vend/xgbutil/xgraphics/text.go @@ -0,0 +1,106 @@ +package xgraphics + +import ( + "image" + "image/color" + "io" + "io/ioutil" + + "github.com/BurntSushi/freetype-go/freetype" + "github.com/BurntSushi/freetype-go/freetype/truetype" +) + +// Text takes an image and, using the freetype package, writes text in the +// position specified on to the image. A color.Color, a font size and a font +// must also be specified. +// Finally, the (x, y) coordinate advanced by the text extents is returned. +// +// Note that the ParseFont helper function can be used to get a *truetype.Font +// value without having to import freetype-go directly. +// +// If you need more control over the 'context' used to draw text (like the DPI), +// then you'll need to ignore this convenience method and use your own. +func (im *Image) Text(x, y int, clr color.Color, fontSize float64, + font *truetype.Font, text string) (int, int, error) { + + // Create a solid color image + textClr := image.NewUniform(clr) + + // Set up the freetype context... mostly boiler plate + c := ftContext(font, fontSize) + c.SetClip(im.Bounds()) + c.SetDst(im) + c.SetSrc(textClr) + + // Now let's actually draw the text... + pt := freetype.Pt(x, y+int(c.PointToFix32(fontSize)>>8)) + newpt, err := c.DrawString(text, pt) + if err != nil { + return 0, 0, err + } + + return int(newpt.X / 256), int(newpt.Y / 256), nil +} + +// Extents returns the *correct* max width and height extents of a string +// given a font. See freetype.MeasureString for the deets. +func Extents(font *truetype.Font, fontSize float64, text string) (int, int) { + c := ftContext(font, fontSize) + w, h, err := c.MeasureString(text) + if err != nil { + return 0, 0 + } + return int(w / 256), int(h / 256) +} + +// Returns the max width and height extents of a string given a font. +// This is calculated by determining the number of pixels in an "em" unit +// for the given font, and multiplying by the number of characters in 'text'. +// Since a particular character may be smaller than one "em" unit, this has +// a tendency to overestimate the extents. +// It is provided because I do not know how to calculate the precise extents +// using freetype-go. +// TODO: This does not currently account for multiple lines. It may never do so. +func TextMaxExtents(font *truetype.Font, fontSize float64, + text string) (width int, height int) { + + c := ftContext(font, fontSize) + emSquarePix := int(c.PointToFix32(fontSize) >> 8) + return len(text) * emSquarePix, emSquarePix +} + +// ftContext does the boiler plate to create a freetype context +func ftContext(font *truetype.Font, fontSize float64) *freetype.Context { + c := freetype.NewContext() + c.SetDPI(72) + c.SetFont(font) + c.SetFontSize(fontSize) + + return c +} + +// ParseFont reads a font file and creates a freetype.Font type +func ParseFont(fontReader io.Reader) (*truetype.Font, error) { + fontBytes, err := ioutil.ReadAll(fontReader) + if err != nil { + return nil, err + } + + font, err := freetype.ParseFont(fontBytes) + if err != nil { + return nil, err + } + + return font, nil +} + +// MustFont panics if err is not nil or if the font is nil. +func MustFont(font *truetype.Font, err error) *truetype.Font { + if err != nil { + panic(err) + } + if font == nil { + panic("font is nil") + } + return font +} diff --git a/vend/xgbutil/xgraphics/util.go b/vend/xgbutil/xgraphics/util.go new file mode 100644 index 0000000..67144f6 --- /dev/null +++ b/vend/xgbutil/xgraphics/util.go @@ -0,0 +1,248 @@ +package xgraphics + +import ( + "fmt" + "image" + "image/color" + "image/draw" + "math" + + "github.com/BurntSushi/graphics-go/graphics" + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/icccm" +) + +/* +xgraphics/util.go contains a variety of image manipulation functions that +are not specific to xgraphics.Image. +*/ + +// Scale is a simple wrapper around graphics.Scale. +func Scale(img image.Image, width, height int) draw.Image { + dimg := image.NewRGBA(image.Rect(0, 0, width, height)) + graphics.Scale(dimg, img) + + return dimg +} + +// Alpha will modify the alpha channel of the image such that: +// existingAlpha = existingAlpha * (givenAlpha / 100.0) +func Alpha(dest *Image, alpha int) { + r := dest.Bounds() + + var a, x, y, i int + for x = r.Min.X; x < r.Max.X; x++ { + for y = r.Min.Y; y < r.Max.Y; y++ { + i = dest.PixOffset(x, y) + a = int(dest.Pix[i+3]) + dest.Pix[i+3] = uint8((a * alpha) / 100) + } + } +} + +// Blend alpha blends the src image (starting at the spt Point) into the +// dest image. +// If you're blending into a solid background color, use BlendBgColor +// instead. (It's more efficient.) +// Blend does not (currently) blend with the destination's alpha channel, +// only the source's alpha channel. +func Blend(dest *Image, src image.Image, sp image.Point) { + rsrc, dsrc := src.Bounds(), dest.Bounds() + _, smxx, _, smxy := rsrc.Min.X, rsrc.Max.X, rsrc.Min.Y, rsrc.Max.Y + dmnx, dmxx, dmny, dmxy := dsrc.Min.X, dsrc.Max.X, dsrc.Min.Y, dsrc.Max.Y + + var sx, dx, sy, dy int + var sr, sg, sb, sa uint32 + var bgra BGRA + var alpha float64 + for sx, dx = sp.X, dmnx; sx < smxx && dx < dmxx; sx, dx = sx+1, dx+1 { + for sy, dy = sp.Y, dmny; sy < smxy && dy < dmxy; sy, dy = sy+1, dy+1 { + sr, sg, sb, sa = src.At(sx, sy).RGBA() + bgra = dest.At(dx, dy).(BGRA) + alpha = float64(uint8(sa)) / 255.0 + + dest.SetBGRA(dx, dy, BGRA{ + blend(uint8(bgra.B), uint8(sb), alpha), + blend(uint8(bgra.G), uint8(sg), alpha), + blend(uint8(bgra.R), uint8(sr), alpha), + 0xff, + }) + } + } +} + +// BlendBgColor blends the Image (receiver) into the background color +// specified. This is more efficient than creating a background image and +// blending with Blend. +func BlendBgColor(dest *Image, c color.Color) { + r := dest.Bounds() + cr32, cg32, cb32, _ := c.RGBA() + cr, cg, cb := uint8(cr32), uint8(cg32), uint8(cb32) + + var bgra BGRA + var alpha float64 + for x := r.Min.X; x < r.Max.X; x++ { + for y := r.Min.Y; y < r.Max.Y; y++ { + bgra = dest.At(x, y).(BGRA) + alpha = float64(bgra.A) / 255.0 + dest.SetBGRA(x, y, BGRA{ + B: blend(cb, bgra.B, alpha), + G: blend(cg, bgra.G, alpha), + R: blend(cr, bgra.R, alpha), + A: 0xff, + }) + } + } +} + +// Blend returns the blended alpha color for src and dest colors. +// This assumes that the destination has alpha = 1. +func BlendBGRA(dest, src BGRA) BGRA { + alpha := float64(src.A) / 255.0 + return BGRA{ + B: blend(dest.B, src.B, alpha), + G: blend(dest.G, src.G, alpha), + R: blend(dest.R, src.R, alpha), + A: 0xff, + } +} + +// blend calculates the value of a color given some alpha value in [0, 1] +// and a source and destination color. Note that this assumes that the +// destination is fully opaque (has an alpha value of 1). +func blend(d, s uint8, alpha float64) uint8 { + return uint8(float64(s)*alpha + float64(d)*(1-alpha)) +} + +// FreePixmap is a convenience function for destroying a pixmap resource +// on the X server. +// If you're using an xgraphics.Image value, then its Destroy method will call +// this for you. +func FreePixmap(X *xgbutil.XUtil, pixid xproto.Pixmap) { + xproto.FreePixmap(X.Conn(), pixid) +} + +// FindIcon takes a window id and attempts to return an xgraphics.Image of +// that window's icon. +// It will first try to look for an icon in _NET_WM_ICON that is closest to +// the size specified. +// If there are no icons in _NET_WM_ICON, then WM_HINTS will be checked for +// an icon. +// If an icon is found from either one and doesn't match the size +// specified, it will be scaled to that size. +// If the width and height are 0, then the largest icon will be returned with +// no scaling. +// If an icon is not found, an error is returned. +func FindIcon(X *xgbutil.XUtil, wid xproto.Window, + width, height int) (*Image, error) { + + var ewmhErr, icccmErr error + + // First try to get a EWMH style icon. + icon, ewmhErr := findIconEwmh(X, wid, width, height) + if ewmhErr != nil { // now look for an icccm-style icon + icon, icccmErr = findIconIcccm(X, wid) + if icccmErr != nil { + return nil, fmt.Errorf("Neither a EWMH-style or ICCCM-style icon "+ + "could be found for window id %x because: %s *AND* %s", + wid, ewmhErr, icccmErr) + } + } + + // We should have a valid xgraphics.Image if we're here. + // If the size doesn't match what's preferred, scale it. + if width != 0 && height != 0 { + if icon.Bounds().Dx() != width || icon.Bounds().Dy() != height { + icon = icon.Scale(width, height) + } + } + return icon, nil +} + +// findIconEwmh helps FindIcon by trying to return an ewmh-style icon that is +// closest to the preferred size specified. +func findIconEwmh(X *xgbutil.XUtil, wid xproto.Window, + width, height int) (*Image, error) { + + icons, err := ewmh.WmIconGet(X, wid) + if err != nil { + return nil, err + } + + icon := FindBestEwmhIcon(width, height, icons) + if icon == nil { + return nil, fmt.Errorf("Could not find any _NET_WM_ICON icon.") + } + + return NewEwmhIcon(X, icon), nil +} + +// findIconIcccm helps FindIcon by trying to return an icccm-style icon. +func findIconIcccm(X *xgbutil.XUtil, wid xproto.Window) (*Image, error) { + hints, err := icccm.WmHintsGet(X, wid) + if err != nil { + return nil, err + } + + // Only continue if the WM_HINTS flags say an icon is specified and + // if at least one of icon pixmap or icon mask is non-zero. + if hints.Flags&icccm.HintIconPixmap == 0 || + (hints.IconPixmap == 0 && hints.IconMask == 0) { + + return nil, fmt.Errorf("No icon found in WM_HINTS.") + } + + return NewIcccmIcon(X, hints.IconPixmap, hints.IconMask) +} + +// FindBestEwmhIcon takes width/height dimensions and a slice of *ewmh.WmIcon +// and finds the best matching icon of the bunch. We always prefer bigger. +// If no icons are bigger than the preferred dimensions, use the biggest +// available. Otherwise, use the smallest icon that is greater than or equal +// to the preferred dimensions. The preferred dimensions is essentially +// what you'll likely scale the resulting icon to. +// If width and height are 0, then the largest icon found will be returned. +func FindBestEwmhIcon(width, height int, icons []ewmh.WmIcon) *ewmh.WmIcon { + // nada nada limonada + if len(icons) == 0 { + return nil + } + + parea := width * height // preferred size + best := -1 + + // If zero area, set it to the largest possible. + if parea == 0 { + parea = math.MaxInt32 + } + + var bestArea, iconArea int + + for i, icon := range icons { + // the first valid icon we've seen; use it! + if best == -1 { + best = i + continue + } + + // load areas for comparison + bestArea = int(icons[best].Width * icons[best].Height) + iconArea = int(icon.Width * icon.Height) + + // We don't always want to accept bigger icons if our best is + // already bigger. But we always want something bigger if our best + // is insufficient. + if (iconArea >= parea && iconArea <= bestArea) || + (bestArea < parea && iconArea > bestArea) { + best = i + } + } + + if best > -1 { + return &icons[best] + } + return nil +} diff --git a/vend/xgbutil/xgraphics/xsurface.go b/vend/xgbutil/xgraphics/xsurface.go new file mode 100644 index 0000000..a431514 --- /dev/null +++ b/vend/xgbutil/xgraphics/xsurface.go @@ -0,0 +1,293 @@ +package xgraphics + +import ( + "fmt" + "image" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/icccm" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/mousebind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xwindow" +) + +/* +xgraphics/xsurface.go contains methods for the Image type that perform X +related requests. Namely, methods that send image data start with 'X'. +*/ + +// XSurfaceSet will set the given window's background to this image's pixmap. +// Note that an image can have multiple surfaces, which is why the window +// id still needs to be passed to XPaint. A call to XSurfaceSet simply tells +// X that the window specified should use the pixmap in Image as its +// background image. +// Note that XSurfaceSet cannot be called on a sub-image. (An error will be +// returned if you do.) +// XSurfaceSet will also allocate an X pixmap if one hasn't been created for +// this image yet. +// (Generating a pixmap id can cause an error, so this call could return +// an error.) +func (im *Image) XSurfaceSet(wid xproto.Window) error { + if im.Subimg { + return fmt.Errorf("XSurfaceSet cannot be called on sub-images." + + "Please set the surface using the original parent image.") + } + if im.Pixmap == 0 { + if err := im.CreatePixmap(); err != nil { + return err + } + } + + // Tell the surface (window) to use this pixmap. + xproto.ChangeWindowAttributes(im.X.Conn(), wid, + xproto.CwBackPixmap, []uint32{uint32(im.Pixmap)}) + return nil +} + +// CreatePixmap allocates an X resource identifier for a pixmap. (It does not +// do any drawing.) You only need to call this if you're using XDraw/XExpPaint. +// If you're using XSurfaceSet/XDraw/XPaint, then CreatePixmap is called for +// you automatically. +func (im *Image) CreatePixmap() error { + // Generate the pixmap id. + pid, err := xproto.NewPixmapId(im.X.Conn()) + if err != nil { + return err + } + + // Now actually create the pixmap. + err = xproto.CreatePixmapChecked(im.X.Conn(), im.X.Screen().RootDepth, + pid, xproto.Drawable(im.X.RootWin()), + uint16(im.Bounds().Dx()), uint16(im.Bounds().Dy())).Check() + if err != nil { + return err + } + + // Now give it to the image. + im.Pixmap = pid + return nil +} + +// XPaint will write the contents of the pixmap to a window. +// Note that painting will do nothing if XDraw hasn't been called. +// XPaint is what switches the buffer (drawn to using XDraw) into the window +// to be visible. That is, multiple calls to XDraw can be made, and the screen +// will only be updated once with a call to XPaint. +func (im *Image) XPaint(wid xproto.Window) { + // We clear the whole window here because sometimes we rely on the tiling + // of a background pixmap. If anyone knows if this is a significant + // performance problem, please let me know. (It seems like the whole area + // of the window is cleared when it is resized anyway.) + xproto.ClearArea(im.X.Conn(), false, wid, 0, 0, 0, 0) +} + +// XExpPaint achieves a similar result as XPaint and XSurfaceSet, but +// uses CopyArea instead of setting a background pixmap and using ClearArea. +// CreatePixmap must be called before using XExpPaint. +// XExpPaint can be called on sub-images. +// x and y correspond to the destination x and y to copy the image to. +// +// This should not be used on the same image with XSurfaceSet and XPaint. +func (im *Image) XExpPaint(wid xproto.Window, x, y int) { + if im.Pixmap == 0 { + return + } + xproto.CopyArea(im.X.Conn(), + xproto.Drawable(im.Pixmap), xproto.Drawable(wid), im.X.GC(), + int16(im.Rect.Min.X), int16(im.Rect.Min.Y), + int16(x), int16(y), + uint16(im.Rect.Dx()), uint16(im.Rect.Dy())) +} + +// XPaintRects is a convenience function for issuing XDraw requests on +// each sub-image generated by the rects in the slice provided, and then +// painting the updated pixmap all at once to the window provided. +// This is efficient because no pixels are copied when taking a SubImage, +// and each XDraw call on a sub-image updates the pixels represented by that +// sub-image and only that sub-image. +func (im *Image) XPaintRects(wid xproto.Window, rects ...image.Rectangle) { + for _, rect := range rects { + if si := im.SubImage(rect).(*Image); si != nil { + si.XDraw() + } + } + im.XPaint(wid) +} + +// XDraw will write the contents of Image to a pixmap. +// Note that this is more like a buffer. Drawing does not put the contents +// on the screen. +// After drawing, it is necessary to call XPaint to put the contents somewhere. +// Draw may return an X error if something has gone horribly wrong. +// +// XSurfaceSet should be called before XDraw. (If not, X will yell at you.) +// More specifically, CreatePixmap needs to be called before XDraw, but it is +// done automatically in XSurfaceSet. +// +// If you're using sub-images to update a particular region of the image, XDraw +// is where you'll see the performance benefit (not XPaint). +func (im *Image) XDraw() { + im.xdraw(false) +} + +// XDrawChecked is the same as XDraw, but issues PutImageChecked requests +// instead. This should *only* be used for debugging purposes, as each +// PutImageChecked request blocks for a round trip to the X server. +func (im *Image) XDrawChecked() error { + return im.xdraw(true) +} + +func (im *Image) xdraw(checked bool) error { + width, height := im.Rect.Dx(), im.Rect.Dy() + + // Put the raw image data into its own slice. + // If this isn't a sub-image, then skip because it isn't necessary. + var data []uint8 + if !im.Subimg { + data = im.Pix + } else { + data = make([]uint8, width*height*4) + for y := im.Rect.Min.Y; y < im.Rect.Max.Y; y++ { + i := (y - im.Rect.Min.Y) * width * 4 + copy(data[i:i+4*width], im.Pix[im.PixOffset(im.Rect.Min.X, y):]) + } + } + + // X's max request size (by default) is (2^16) * 4 = 262144 bytes, which + // corresponds precisely to a 256x256 sized image with 32 bits per pixel. + // Thus, we check the size of the image data and calculate the number of + // rows of the image we'll send in each request. If a single row of an + // image exceeds the max request length, we're in trouble. N.B. The + // constant 28 comes from the fixed size part of a PutImage request. + rowsPer := (xgbutil.MaxReqSize - 28) / (width * 4) + bytesPer := rowsPer * width * 4 + + // The start x position of what we're sending. Doesn't change. + xpos := im.Rect.Min.X + + // The start y position of what we're sending. Increases based on the + // number of rows of the image we send in each request. + ypos := im.Rect.Min.Y + + // The height of each PutImage request. It's always rowsPer, unless its + // the last request and we're not sending the maximum number of bytes. + heightPer := 0 + + // The start and end positions of the raw bytes being sent. + start, end := 0, 0 + + // The sliced data we're sending, for convenience. + var toSend []byte + + for end < len(data) { + end = start + bytesPer + if end > len(data) { // make sure end doesn't extend beyond data + end = len(data) + } + + toSend = data[start:end] + heightPer = len(toSend) / 4 / width + + if checked { + err := xproto.PutImageChecked( + im.X.Conn(), xproto.ImageFormatZPixmap, + xproto.Drawable(im.Pixmap), im.X.GC(), + uint16(width), uint16(heightPer), int16(xpos), int16(ypos), + 0, 24, toSend).Check() + if err != nil { + return err + } + } else { + xproto.PutImage(im.X.Conn(), xproto.ImageFormatZPixmap, + xproto.Drawable(im.Pixmap), im.X.GC(), + uint16(width), uint16(heightPer), int16(xpos), int16(ypos), + 0, 24, toSend) + } + start = end + ypos += rowsPer + } + + return nil +} + +// XShow creates a new window and paints the image to the window. +// This is useful for debugging, or if you're creating an image viewer. +// XShow also returns the xwindow.Window value, in case you want to do +// further processing. (Like attach event handlers.) +func (im *Image) XShow() *xwindow.Window { + return im.XShowExtra("", false) +} + +// XShowName is just like XShow, except it sets the name of the window to the +// name provided, and will quit the current event loop if 'quit' is true when +// the window is closed. +// If name is empty and quit is false, then the behavior is precisely the same +// as XShow. +func (im *Image) XShowExtra(name string, quit bool) *xwindow.Window { + if len(name) == 0 { + name = "xgbutil Image Window" + } + w, h := im.Rect.Dx(), im.Rect.Dy() + + win, err := xwindow.Generate(im.X) + if err != nil { + xgbutil.Logger.Printf("Could not generate new window id: %s", err) + return nil + } + + // Create a very simple window with dimensions equal to the image. + win.Create(im.X.RootWin(), 0, 0, w, h, 0) + + // Make this window close gracefully. + win.WMGracefulClose(func(w *xwindow.Window) { + xevent.Detach(w.X, w.Id) + keybind.Detach(w.X, w.Id) + mousebind.Detach(w.X, w.Id) + w.Destroy() + + if quit { + xevent.Quit(w.X) + } + }) + + // Set WM_STATE so it is interpreted as a top-level window. + err = icccm.WmStateSet(im.X, win.Id, &icccm.WmState{ + State: icccm.StateNormal, + }) + if err != nil { // not a fatal error + xgbutil.Logger.Printf("Could not set WM_STATE: %s", err) + } + + // Set WM_NORMAL_HINTS so the window can't be resized. + err = icccm.WmNormalHintsSet(im.X, win.Id, &icccm.NormalHints{ + Flags: icccm.SizeHintPMinSize | icccm.SizeHintPMaxSize, + MinWidth: uint(w), + MinHeight: uint(h), + MaxWidth: uint(w), + MaxHeight: uint(h), + }) + if err != nil { // not a fatal error + xgbutil.Logger.Printf("Could not set WM_NORMAL_HINTS: %s", err) + } + + // Set _NET_WM_NAME so it looks nice. + err = ewmh.WmNameSet(im.X, win.Id, name) + if err != nil { // not a fatal error + xgbutil.Logger.Printf("Could not set _NET_WM_NAME: %s", err) + } + + // Paint our image before mapping. + im.XSurfaceSet(win.Id) + im.XDraw() + im.XPaint(win.Id) + + // Now we can map, since we've set all our properties. + // (The initial map is when the window manager starts managing.) + win.Map() + + return win +} diff --git a/vend/xgbutil/xinerama/doc.go b/vend/xgbutil/xinerama/doc.go new file mode 100644 index 0000000..83fbbf3 --- /dev/null +++ b/vend/xgbutil/xinerama/doc.go @@ -0,0 +1,9 @@ +/* +Package xinerama provides a convenience function to retrieve the geometry of +all active heads sorted in order from left to right and then top to bottom. +While Xinerama is an old extension that isn't often used in lieu of RandR and +TwinView, it can still be used to query for information about all active heads. +That is, even if TwinView or RandR is being used, Xinerama will still report +the correct geometry of each head. +*/ +package xinerama diff --git a/vend/xgbutil/xinerama/xinerama.go b/vend/xgbutil/xinerama/xinerama.go new file mode 100644 index 0000000..e7c8eb4 --- /dev/null +++ b/vend/xgbutil/xinerama/xinerama.go @@ -0,0 +1,66 @@ +package xinerama + +import "sort" + +import ( + "github.com/jezek/xgb/xinerama" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/xrect" +) + +// Alias so we use it as a receiver to satisfy sort.Interface +type Heads []xrect.Rect + +// Len satisfies 'Len' in sort.Interface. +func (hds Heads) Len() int { + return len(hds) +} + +// Less satisfies 'Less' in sort.Interface. +func (hds Heads) Less(i int, j int) bool { + return hds[i].X() < hds[j].X() || (hds[i].X() == hds[j].X() && + hds[i].Y() < hds[j].Y()) +} + +// Swap does just that. Nothing to see here... +func (hds Heads) Swap(i int, j int) { + hds[i], hds[j] = hds[j], hds[i] +} + +// PhyiscalHeads returns the list of heads in a physical ordering. +// Namely, left to right then top to bottom. (Defined by (X, Y).) +// Xinerama must have been initialized, otherwise the xinerama.QueryScreens +// request will panic. +// PhysicalHeads also checks to make sure each rectangle has a unique (x, y) +// tuple, so as not to return the geometry of cloned displays. +// (At present moment, xgbutil initializes Xinerama automatically during +// initial connection.) +func PhysicalHeads(xu *xgbutil.XUtil) (Heads, error) { + xinfo, err := xinerama.QueryScreens(xu.Conn()).Reply() + if err != nil { + return nil, err + } + + hds := make(Heads, 0) + for _, info := range xinfo.ScreenInfo { + head := xrect.New(int(info.XOrg), int(info.YOrg), + int(info.Width), int(info.Height)) + + // Maybe Xinerama is enabled, but we have cloned displays... + unique := true + for _, h := range hds { + if h.X() == head.X() && h.Y() == head.Y() { + unique = false + break + } + } + + if unique { + hds = append(hds, head) + } + } + + sort.Sort(hds) + return hds, nil +} diff --git a/vend/xgbutil/xprop/atom.go b/vend/xgbutil/xprop/atom.go new file mode 100644 index 0000000..6d857c4 --- /dev/null +++ b/vend/xgbutil/xprop/atom.go @@ -0,0 +1,103 @@ +package xprop + +/* +xprop/atom.go contains functions related to interning atoms and retrieving +atom names from an atom identifier. + +It also manages an atom cache so that once an atom is interned from the X +server, all future atom interns use that value. (So that one and only one +request is sent for interning each atom.) +*/ + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// Atm is a short alias for Atom in the common case of interning an atom. +// Namely, interning the atom always succeeds. (If the atom does not already +// exist, a new one is created.) +func Atm(xu *xgbutil.XUtil, name string) (xproto.Atom, error) { + aid, err := Atom(xu, name, false) + if err != nil { + return 0, err + } + if aid == 0 { + return 0, fmt.Errorf("Atm: '%s' returned an identifier of 0.", name) + } + + return aid, err +} + +// Atom interns an atom and panics if there is any error. +func Atom(xu *xgbutil.XUtil, name string, + onlyIfExists bool) (xproto.Atom, error) { + + // Check the cache first + if aid, ok := atomGet(xu, name); ok { + return aid, nil + } + + reply, err := xproto.InternAtom(xu.Conn(), onlyIfExists, + uint16(len(name)), name).Reply() + if err != nil { + return 0, fmt.Errorf("Atom: Error interning atom '%s': %s", name, err) + } + + // If we're here, it means we didn't have this atom cached. So cache it! + cacheAtom(xu, name, reply.Atom) + + return reply.Atom, nil +} + +// AtomName fetches a string representation of an ATOM given its integer id. +func AtomName(xu *xgbutil.XUtil, aid xproto.Atom) (string, error) { + // Check the cache first + if atomName, ok := atomNameGet(xu, aid); ok { + return string(atomName), nil + } + + reply, err := xproto.GetAtomName(xu.Conn(), aid).Reply() + if err != nil { + return "", fmt.Errorf("AtomName: Error fetching name for ATOM "+ + "id '%d': %s", aid, err) + } + + // If we're here, it means we didn't have ths ATOM id cached. So cache it. + atomName := string(reply.Name) + cacheAtom(xu, atomName, aid) + + return atomName, nil +} + +// atomGet retrieves an atom identifier from a cache if it exists. +func atomGet(xu *xgbutil.XUtil, name string) (xproto.Atom, bool) { + xu.AtomsLck.RLock() + defer xu.AtomsLck.RUnlock() + + aid, ok := xu.Atoms[name] + return aid, ok +} + +// atomNameGet retrieves an atom name from a cache if it exists. +func atomNameGet(xu *xgbutil.XUtil, aid xproto.Atom) (string, bool) { + xu.AtomNamesLck.RLock() + defer xu.AtomNamesLck.RUnlock() + + name, ok := xu.AtomNames[aid] + return name, ok +} + +// cacheAtom puts an atom into the cache. +func cacheAtom(xu *xgbutil.XUtil, name string, aid xproto.Atom) { + xu.AtomsLck.Lock() + xu.AtomNamesLck.Lock() + defer xu.AtomsLck.Unlock() + defer xu.AtomNamesLck.Unlock() + + xu.Atoms[name] = aid + xu.AtomNames[aid] = name +} diff --git a/vend/xgbutil/xprop/doc.go b/vend/xgbutil/xprop/doc.go new file mode 100644 index 0000000..6dcf761 --- /dev/null +++ b/vend/xgbutil/xprop/doc.go @@ -0,0 +1,40 @@ +/* +Package xprop provides a cache for interning atoms and helper functions for +dealing with GetProperty and ChangeProperty X requests. + +Atoms + +Atoms in X are interned, meaning that strings are assigned unique integer +identifiers. This minimizes the amount of data transmitted over an X connection. + +Once atoms have been interned, they are never changed while the X server is +running. xgbutil takes advantage of this invariant and will only issue an +intern atom request once and cache the result. + +To use the xprop package to intern an atom, use Atom: + + atom, err := xprop.Atom(XUtilValue, "THE_ATOM_NAME", false) + if err == nil { + println("The atom number: ", atom.Atom) + } + +The 'false' parameter corresponds to the 'only_if_exists' parameter of the +X InternAtom request. When it's false, the atom being interned always returns +a non-zero atom number---even if the string being interned hasn't been interned +before. If 'only_if_exists' is true, the atom being interned will return a 0 +atom number if it hasn't already been interned. + +The typical case is to set 'only_if_exists' to false. To this end, xprop.Atm is +an alias that always sets this value to false. + +The reverse can also be done: getting an atom string if you have an atom +number. This can be done with the xprop.AtomName function. + +Properties + +The other facility of xprop is to help with the use of GetProperty and +ChangeProperty. Please see the source code of the ewmh package for plenty of +examples. + +*/ +package xprop diff --git a/vend/xgbutil/xprop/xprop.go b/vend/xgbutil/xprop/xprop.go new file mode 100644 index 0000000..19b8b7b --- /dev/null +++ b/vend/xgbutil/xprop/xprop.go @@ -0,0 +1,270 @@ +package xprop + +import ( + "fmt" + + "github.com/jezek/xgb" + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" +) + +// GetProperty abstracts the messiness of calling xgb.GetProperty. +func GetProperty(xu *xgbutil.XUtil, win xproto.Window, atom string) ( + *xproto.GetPropertyReply, error) { + + atomId, err := Atm(xu, atom) + if err != nil { + return nil, err + } + + reply, err := xproto.GetProperty(xu.Conn(), false, win, atomId, + xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() + + if err != nil { + return nil, fmt.Errorf("GetProperty: Error retrieving property '%s' "+ + "on window %x: %s", atom, win, err) + } + + if reply.Format == 0 { + return nil, fmt.Errorf("GetProperty: No such property '%s' on "+ + "window %x.", atom, win) + } + + return reply, nil +} + +// ChangeProperty abstracts the semi-nastiness of xgb.ChangeProperty. +func ChangeProp(xu *xgbutil.XUtil, win xproto.Window, format byte, prop string, + typ string, data []byte) error { + + propAtom, err := Atm(xu, prop) + if err != nil { + return err + } + + typAtom, err := Atm(xu, typ) + if err != nil { + return err + } + + return xproto.ChangePropertyChecked(xu.Conn(), xproto.PropModeReplace, win, + propAtom, typAtom, format, + uint32(len(data)/(int(format)/8)), data).Check() +} + +// ChangeProperty32 makes changing 32 bit formatted properties easier +// by constructing the raw X data for you. +func ChangeProp32(xu *xgbutil.XUtil, win xproto.Window, prop string, typ string, + data ...uint) error { + + buf := make([]byte, len(data)*4) + for i, datum := range data { + xgb.Put32(buf[(i*4):], uint32(datum)) + } + + return ChangeProp(xu, win, 32, prop, typ, buf) +} + +// WindowToUint is a covenience function for converting []xproto.Window +// to []uint. +func WindowToInt(ids []xproto.Window) []uint { + ids32 := make([]uint, len(ids)) + for i, v := range ids { + ids32[i] = uint(v) + } + return ids32 +} + +// AtomToInt is a covenience function for converting []xproto.Atom +// to []uint. +func AtomToUint(ids []xproto.Atom) []uint { + ids32 := make([]uint, len(ids)) + for i, v := range ids { + ids32[i] = uint(v) + } + return ids32 +} + +// StrToAtoms is a convenience function for converting +// []string to []uint32 atoms. +// NOTE: If an atom name in the list doesn't exist, it will be created. +func StrToAtoms(xu *xgbutil.XUtil, atomNames []string) ([]uint, error) { + var err error + atoms := make([]uint, len(atomNames)) + for i, atomName := range atomNames { + a, err := Atom(xu, atomName, false) + if err != nil { + return nil, err + } + atoms[i] = uint(a) + } + return atoms, err +} + +// PropValAtom transforms a GetPropertyReply struct into an ATOM name. +// The property reply must be in 32 bit format. +func PropValAtom(xu *xgbutil.XUtil, reply *xproto.GetPropertyReply, + err error) (string, error) { + + if err != nil { + return "", err + } + if reply.Format != 32 { + return "", fmt.Errorf("PropValAtom: Expected format 32 but got %d", + reply.Format) + } + + return AtomName(xu, xproto.Atom(xgb.Get32(reply.Value))) +} + +// PropValAtoms is the same as PropValAtom, except that it returns a slice +// of atom names. Also must be 32 bit format. +// This is a method of an XUtil struct, unlike the other 'PropVal...' functions. +func PropValAtoms(xu *xgbutil.XUtil, reply *xproto.GetPropertyReply, + err error) ([]string, error) { + + if err != nil { + return nil, err + } + if reply.Format != 32 { + return nil, fmt.Errorf("PropValAtoms: Expected format 32 but got %d", + reply.Format) + } + + ids := make([]string, reply.ValueLen) + vals := reply.Value + for i := 0; len(vals) >= 4; i++ { + ids[i], err = AtomName(xu, xproto.Atom(xgb.Get32(vals))) + if err != nil { + return nil, err + } + + vals = vals[4:] + } + return ids, nil +} + +// PropValWindow transforms a GetPropertyReply struct into an X resource +// window identifier. +// The property reply must be in 32 bit format. +func PropValWindow(reply *xproto.GetPropertyReply, + err error) (xproto.Window, error) { + + if err != nil { + return 0, err + } + if reply.Format != 32 { + return 0, fmt.Errorf("PropValId: Expected format 32 but got %d", + reply.Format) + } + return xproto.Window(xgb.Get32(reply.Value)), nil +} + +// PropValWindows is the same as PropValWindow, except that it returns a slice +// of identifiers. Also must be 32 bit format. +func PropValWindows(reply *xproto.GetPropertyReply, + err error) ([]xproto.Window, error) { + + if err != nil { + return nil, err + } + if reply.Format != 32 { + return nil, fmt.Errorf("PropValIds: Expected format 32 but got %d", + reply.Format) + } + + ids := make([]xproto.Window, reply.ValueLen) + vals := reply.Value + for i := 0; len(vals) >= 4; i++ { + ids[i] = xproto.Window(xgb.Get32(vals)) + vals = vals[4:] + } + return ids, nil +} + +// PropValNum transforms a GetPropertyReply struct into an unsigned +// integer. Useful when the property value is a single integer. +func PropValNum(reply *xproto.GetPropertyReply, err error) (uint, error) { + if err != nil { + return 0, err + } + if reply.Format != 32 { + return 0, fmt.Errorf("PropValNum: Expected format 32 but got %d", + reply.Format) + } + return uint(xgb.Get32(reply.Value)), nil +} + +// PropValNums is the same as PropValNum, except that it returns a slice +// of integers. Also must be 32 bit format. +func PropValNums(reply *xproto.GetPropertyReply, err error) ([]uint, error) { + if err != nil { + return nil, err + } + if reply.Format != 32 { + return nil, fmt.Errorf("PropValIds: Expected format 32 but got %d", + reply.Format) + } + + nums := make([]uint, reply.ValueLen) + vals := reply.Value + for i := 0; len(vals) >= 4; i++ { + nums[i] = uint(xgb.Get32(vals)) + vals = vals[4:] + } + return nums, nil +} + +// PropValNum64 transforms a GetPropertyReply struct into a 64 bit +// integer. Useful when the property value is a single integer. +func PropValNum64(reply *xproto.GetPropertyReply, err error) (int64, error) { + if err != nil { + return 0, err + } + if reply.Format != 32 { + return 0, fmt.Errorf("PropValNum: Expected format 32 but got %d", + reply.Format) + } + return int64(xgb.Get32(reply.Value)), nil +} + +// PropValStr transforms a GetPropertyReply struct into a string. +// Useful when the property value is a null terminated string represented +// by integers. Also must be 8 bit format. +func PropValStr(reply *xproto.GetPropertyReply, err error) (string, error) { + if err != nil { + return "", err + } + if reply.Format != 8 { + return "", fmt.Errorf("PropValStr: Expected format 8 but got %d", + reply.Format) + } + return string(reply.Value), nil +} + +// PropValStrs is the same as PropValStr, except that it returns a slice +// of strings. The raw byte string is a sequence of null terminated strings, +// which is translated into a slice of strings. +func PropValStrs(reply *xproto.GetPropertyReply, err error) ([]string, error) { + if err != nil { + return nil, err + } + if reply.Format != 8 { + return nil, fmt.Errorf("PropValStrs: Expected format 8 but got %d", + reply.Format) + } + + var strs []string + sstart := 0 + for i, c := range reply.Value { + if c == 0 { + strs = append(strs, string(reply.Value[sstart:i])) + sstart = i + 1 + } + } + if sstart < int(reply.ValueLen) { + strs = append(strs, string(reply.Value[sstart:])) + } + return strs, nil +} diff --git a/vend/xgbutil/xrect/doc.go b/vend/xgbutil/xrect/doc.go new file mode 100644 index 0000000..e15a312 --- /dev/null +++ b/vend/xgbutil/xrect/doc.go @@ -0,0 +1,12 @@ +/* +Package xrect defines a Rect interface and an XRect type implementing the Rect +interface for working with X rectangles. Namely, X rectangles are specified by +the 4-tuple (x, y, width, height) where the origin is the top-left corner and +the width and height *must* be non-zero. + +Some of the main features of this package include finding the area of +intersection of two rectangles, finding the largest overlap between some +rectangle and a set of rectangles, applying partial struts to rectangles +representing all active heads, and a function to subtract two rectangles. +*/ +package xrect diff --git a/vend/xgbutil/xrect/xrect.go b/vend/xgbutil/xrect/xrect.go new file mode 100644 index 0000000..0a01614 --- /dev/null +++ b/vend/xgbutil/xrect/xrect.go @@ -0,0 +1,282 @@ +package xrect + +import "fmt" + +// Define a base and simple Rect interface. +type Rect interface { + X() int + Y() int + Width() int + Height() int + XSet(x int) + YSet(y int) + WidthSet(width int) + HeightSet(height int) + Pieces() (int, int, int, int) +} + +// RectPieces just returns a four-tuple of x, y, width and height +func RectPieces(xr Rect) (int, int, int, int) { + return xr.X(), xr.Y(), xr.Width(), xr.Height() +} +func Pieces(xr Rect) (int, int, int, int) { + return RectPieces(xr) +} + +// Provide a simple implementation of a rect. +// Maybe this will be all we need? +type XRect struct { + x, y int + width, height int +} + +// Provide the ability to construct an XRect. +func New(x, y, w, h int) *XRect { + return &XRect{x, y, w, h} +} + +func (r *XRect) String() string { + return fmt.Sprintf("[(%d, %d) %dx%d]", r.x, r.y, r.width, r.height) +} + +// Satisfy the Rect interface +func (r *XRect) X() int { + return r.x +} + +func (r *XRect) Y() int { + return r.y +} + +func (r *XRect) Width() int { + return r.width +} + +func (r *XRect) Height() int { + return r.height +} + +func (r *XRect) XSet(x int) { + r.x = x +} + +func (r *XRect) YSet(y int) { + r.y = y +} + +func (r *XRect) WidthSet(width int) { + r.width = width +} + +func (r *XRect) HeightSet(height int) { + r.height = height +} + +// Pieces just returns a four-tuple of x, y, width and height +func (r *XRect) Pieces() (int, int, int, int) { + return r.X(), r.Y(), r.Width(), r.Height() +} + +// Valid returns whether a rectangle is valid or not. i.e., a width AND height +// not equal to zero. +func Valid(r Rect) bool { + return r.Width() != 0 && r.Height() != 0 +} + +// Subtract subtracts r2 from r1 and returns the result as a +// new slice of Rects. +// Basically, rectangle subtraction works by cutting r2 out of r1, and returning +// the resulting rectangles. +// If r1 does not overlap r2, then only one rectangle is returned and is +// equivalent to r1. +// If r2 covers r1, then no rectangles are returned. +// If r1 covers r2, then four rectangles are returned. +// If r2 partially overlaps r1, then one, two or three rectangles are returned. +func Subtract(r1 Rect, r2 Rect) []Rect { + r1x1, r1y1, r1w, r1h := r1.Pieces() + r2x1, r2y1, r2w, r2h := r2.Pieces() + + r1x2, r1y2 := r1x1+r1w, r1y1+r1h + r2x2, r2y2 := r2x1+r2w, r2y1+r2h + + // No intersection; return r1. + if r2x1 >= r1x2 || r1x1 >= r2x2 || r2y1 >= r1y2 || r1y1 >= r2y2 { + return []Rect{New(r1x1, r1y1, r1w, r1h)} + } + + // r2 covers r1; so subtraction yields no rectangles. + if r1x1 >= r2x1 && r1y1 >= r2y1 && r1x2 <= r2x2 && r1y2 <= r2y2 { + return []Rect{} + } + + // Now generate each of the four possible rectangles and add them only + // if they are valid (i.e., width/height >= 1) + result := make([]Rect, 0, 4) + + rect1 := New(r1x1, r1y1, r1w, r2y1-r1y1) + rect2 := New(r1x1, r1y1, r2x1-r1x1, r1h) + rect3 := New(r1x1, r2y2, r1w, r1h-((r2y1-r1y1)+r2h)) + rect4 := New(r2x2, r1y1, r1w-((r2x1-r1x1)+r2w), r1h) + + if Valid(rect1) { + result = append(result, rect1) + } + if Valid(rect2) { + result = append(result, rect2) + } + if Valid(rect3) { + result = append(result, rect3) + } + if Valid(rect4) { + result = append(result, rect4) + } + + return result +} + +// IntersectArea takes two rectangles satisfying the Rect interface and +// returns the area of their intersection. If there is no intersection, return +// 0 area. +func IntersectArea(r1 Rect, r2 Rect) int { + x1, y1, w1, h1 := RectPieces(r1) + x2, y2, w2, h2 := RectPieces(r2) + if x2 < x1+w1 && x2+w2 > x1 && y2 < y1+h1 && y2+h2 > y1 { + iw := min(x1+w1-1, x2+w2-1) - max(x1, x2) + 1 + ih := min(y1+h1-1, y2+h2-1) - max(y1, y2) + 1 + return iw * ih + } + + return 0 +} + +// LargestOverlap returns the index of the rectangle in 'haystack' that has the +// largest overlap with the rectangle 'needle'. +// This is commonly used to find which monitor a window should belong on. +// (Since it can technically be partially displayed on more than one monitor +// at a time.) +// Be careful, the return value can be -1 if there is no overlap. +func LargestOverlap(needle Rect, haystack []Rect) int { + biggestArea := 0 + reti := -1 + + var area int + for i, possible := range haystack { + area = IntersectArea(needle, possible) + if area > biggestArea { + biggestArea = area + reti = i + } + } + return reti +} + +// ApplyStrut takes a list of Rects (typically the rectangles that represent +// each physical head in this case), the root window geometry, +// and a set of parameters representing a +// strut, and modifies the list of Rects to account for that strut. +// That is, it shrinks each rect. +// Note that if struts overlap, the *most restrictive* one is used. This seems +// like the most sensible response to a weird scenario. +// (If you don't have a partial strut, just use '0' for the extra fields.) +// See xgbutil/examples/workarea-struts for an example of how to use this to +// get accurate workarea for each physical head. +func ApplyStrut(rects []Rect, rootWidth, rootHeight uint, + left, right, top, bottom, + left_start_y, left_end_y, right_start_y, right_end_y, + top_start_x, top_end_x, bottom_start_x, bottom_end_x uint) { + + var nx, ny uint // 'n*' are new values that may or may not be used + var nw, nh uint + var x_, y_, w_, h_ int + var x, y, w, h uint + var bt, tp, lt, rt bool + rWidth, rHeight := rootWidth, rootHeight + + // The essential idea of struts, and particularly partial struts, is that + // one piece of a border of the screen can be "reserved" for some + // special windows like docks, panels, taskbars and system trays. + // Since we assume that one window can only reserve one piece of a border + // (either top, left, right or bottom), we iterate through each rect + // in our list and check if that rect is affected by the given strut. + // If it is, we modify the current rect appropriately. + // TODO: Fix this so old school _NET_WM_STRUT can work too. It actually + // should be pretty simple: change conditions like 'if tp' to + // 'if tp || (top_start_x == 0 && top_end_x == 0 && top != 0)'. + // Thus, we would end up changing every rect, which is what old school + // struts should do. We may also make a conscious choice to ignore them + // when 'rects' has more than one rect, since the old school struts will + // typically result in undesirable behavior. + for _, rect := range rects { + x_, y_, w_, h_ = RectPieces(rect) + x, y, w, h = uint(x_), uint(y_), uint(w_), uint(h_) + + bt = bottom_start_x != bottom_end_x && + (xInRect(bottom_start_x, rect) || xInRect(bottom_end_x, rect)) + tp = top_start_x != top_end_x && + (xInRect(top_start_x, rect) || xInRect(top_end_x, rect)) + lt = left_start_y != left_end_y && + (yInRect(left_start_y, rect) || yInRect(left_end_y, rect)) + rt = right_start_y != right_end_y && + (yInRect(right_start_y, rect) || yInRect(right_end_y, rect)) + + if bt { + nh = h - (bottom - ((rHeight - h) - y)) + if nh < uint(rect.Height()) { + rect.HeightSet(int(nh)) + } + } else if tp { + nh = h - (top - y) + if nh < uint(rect.Height()) { + rect.HeightSet(int(nh)) + } + + ny = top + if ny > uint(rect.Y()) { + rect.YSet(int(ny)) + } + } else if rt { + nw = w - (right - ((rWidth - w) - x)) + if nw < uint(rect.Width()) { + rect.WidthSet(int(nw)) + } + } else if lt { + nw = w - (left - x) + if nw < uint(rect.Width()) { + rect.WidthSet(int(nw)) + } + + nx = left + if nx > uint(rect.X()) { + rect.XSet(int(nx)) + } + } + } +} + +// xInRect is whether a particular x-coordinate is vertically constrained by +// a rectangle. +func xInRect(xtest uint, rect Rect) bool { + x, _, w, _ := RectPieces(rect) + return int(xtest) >= x && int(xtest) < (x+w) +} + +// yInRect is whether a particular y-coordinate is horizontally constrained by +// a rectangle. +func yInRect(ytest uint, rect Rect) bool { + _, y, _, h := RectPieces(rect) + return int(ytest) >= y && int(ytest) < (y+h) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/vend/xgbutil/xwindow/doc.go b/vend/xgbutil/xwindow/doc.go new file mode 100644 index 0000000..c820812 --- /dev/null +++ b/vend/xgbutil/xwindow/doc.go @@ -0,0 +1,39 @@ +/* +Package xwindow defines a window type that provides easy access to common +window operations while hiding many of the more obscure X parameters. Examples +of such window operations include, but are not limited to, creating a window, +mapping a window, moving/resizing a window and getting the geometry of a +top-level client window including the window manager's decorations. + +New and Generate functions are provided as constructors. New should be used +when you already have a window id, and it cannot fail. Generate should be used +when you need to allocate a new window identifier. Since allocating a new +window identifier can fail, an error could be returned. + +Note that methods starting with 'WM' should only be used with a window manager +running that supports the EWMH specification. You should otherwise try to use +the corresponding methods without the 'WM' prefix. + +A quick example + +To create a window with a blue background that is 500 pixels wide and 200 +pixels tall and map the window, use something like: + + win, err := xwindow.Generate(X) + if err != nil { + log.Fatal(err) + } + win.Create(X.RootWin(), 0, 0, 500, 200, xproto.CwBackPixel, 0x0000ff) + win.Map() + +You may also want to use CreateChecked instead of Create if you want to see if +there was an error when creating a window. + +More examples + +The xwindow package is used in many of the examples in the examples directory +of the xgbutil package. Of particular interest is window-name-sizes, which +prints the name and size of each top-level client window. (The geometry of the +window is found using DecorGeometry.) +*/ +package xwindow diff --git a/vend/xgbutil/xwindow/ewmh.go b/vend/xgbutil/xwindow/ewmh.go new file mode 100644 index 0000000..ba1048a --- /dev/null +++ b/vend/xgbutil/xwindow/ewmh.go @@ -0,0 +1,102 @@ +package xwindow + +/* +xwindow/ewmh.go contains several methods that rely on EWMH support in +the currently running window manager. +*/ + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/ewmh" + "github.com/jezek/xgbutil/xrect" +) + +// DecorGeometry retrieves the client's width and height including decorations. +// This can be tricky. In a non-parenting window manager, the width/height of +// a client can be found by inspecting the client directly. In a reparenting +// window manager like Openbox, the parent of the client reflects the true +// width/height. Still yet, in KWin, it's the parent of the parent of the +// client that reflects the true width/height. +// The idea then is to traverse up the tree until we hit the root window. +// Therefore, we're at a top-level window which should accurately reflect +// the width/height. +func (w *Window) DecorGeometry() (xrect.Rect, error) { + parent := w + for { + tempParent, err := parent.Parent() + if err != nil || tempParent.Id == w.X.RootWin() { + break + } + parent = tempParent + } + return RawGeometry(w.X, xproto.Drawable(parent.Id)) +} + +// WMMoveResize is an accurate means of resizing a window, accounting for +// decorations. Usually, the x,y coordinates are fine---we just need to +// adjust the width and height. +// This should be used when moving/resizing top-level client windows with +// reparenting window managers that support EWMH. +func (w *Window) WMMoveResize(x, y, width, height int) error { + neww, newh, err := adjustSize(w.X, w.Id, width, height) + if err != nil { + return err + } + return ewmh.MoveresizeWindowExtra(w.X, w.Id, x, y, neww, newh, + xproto.GravityBitForget, 2, true, true) +} + +// WMMove changes the position of a window without touching the size. +// This should be used when moving a top-level client window with +// reparenting winow managers that support EWMH. +func (w *Window) WMMove(x, y int) error { + return ewmh.MoveWindow(w.X, w.Id, x, y) +} + +// WMResize changes the size of a window without touching the position. +// This should be used when resizing a top-level client window with +// reparenting window managers that support EWMH. +func (w *Window) WMResize(width, height int) error { + neww, newh, err := adjustSize(w.X, w.Id, width, height) + if err != nil { + return err + } + return ewmh.ResizeWindow(w.X, w.Id, neww, newh) +} + +// adjustSize takes a client and dimensions, and adjust them so that they'll +// account for window decorations. For example, if you want a window to be +// 200 pixels wide, a window manager will typically determine that as +// you wanting the *client* to be 200 pixels wide. The end result is that +// the client plus decorations ends up being +// (200 + left decor width + right decor width) pixels wide. Which is probably +// not what you want. Therefore, transform 200 into +// 200 - decoration window width - client window width. +// Similarly for height. +func adjustSize(xu *xgbutil.XUtil, win xproto.Window, + w, h int) (int, int, error) { + + // raw client geometry + cGeom, err := RawGeometry(xu, xproto.Drawable(win)) + if err != nil { + return 0, 0, err + } + + // geometry with decorations + pGeom, err := RawGeometry(xu, xproto.Drawable(win)) + if err != nil { + return 0, 0, err + } + + neww := w - (pGeom.Width() - cGeom.Width()) + newh := h - (pGeom.Height() - cGeom.Height()) + if neww < 1 { + neww = 1 + } + if newh < 1 { + newh = 1 + } + return neww, newh, nil +} diff --git a/vend/xgbutil/xwindow/icccm.go b/vend/xgbutil/xwindow/icccm.go new file mode 100644 index 0000000..e6b9b08 --- /dev/null +++ b/vend/xgbutil/xwindow/icccm.go @@ -0,0 +1,92 @@ +package xwindow + +import ( + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/icccm" + "github.com/jezek/xgbutil/xevent" +) + +// WMGracefulClose will do all the necessary setup to implement the +// WM_DELETE_WINDOW protocol. This will prevent well-behaving window managers +// from killing your client whenever one of your windows is closed. (Killing +// a client is bad because it will destroy your X connection and any other +// clients you have open.) +// You must provide a callback function that is called when the window manager +// asks you to close your window. (You may provide some means of confirmation +// to the user, i.e., "Do you really want to quit?", but you should probably +// just wrap things up and call DestroyWindow.) +func (w *Window) WMGracefulClose(cb func(w *Window)) { + // Get the current protocols so we don't overwrite anything. + prots, _ := icccm.WmProtocolsGet(w.X, w.Id) + + // If WM_DELETE_WINDOW isn't here, add it. Otherwise, move on. + wmdelete := false + for _, prot := range prots { + if prot == "WM_DELETE_WINDOW" { + wmdelete = true + break + } + } + if !wmdelete { + icccm.WmProtocolsSet(w.X, w.Id, append(prots, "WM_DELETE_WINDOW")) + } + + // Attach a ClientMessage event handler. It will determine whether the + // ClientMessage is a 'close' request, and if so, run the callback 'cb' + // provided. + xevent.ClientMessageFun( + func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { + if icccm.IsDeleteProtocol(X, ev) { + cb(w) + } + }).Connect(w.X, w.Id) +} + +// WMTakeFocus will do all the necessary setup to support the WM_TAKE_FOCUS +// protocol using the "LocallyActive" input model described in Section 4.1.7 +// of the ICCCM. Namely, listening to ClientMessage events and running the +// callback function provided when a WM_TAKE_FOCUS ClientMessage has been +// received. +// +// Typically, the callback function should include a call to SetInputFocus +// with the "Parent" InputFocus type, the sub-window id of the window that +// should have focus, and the 'tstamp' timestamp. +func (w *Window) WMTakeFocus(cb func(w *Window, tstamp xproto.Timestamp)) { + // Make sure the Input flag is set to true in WM_HINTS. We first + // must retrieve the current WM_HINTS, so we don't overwrite the flags. + curFlags := uint(0) + if hints, err := icccm.WmHintsGet(w.X, w.Id); err == nil { + curFlags = hints.Flags + } + icccm.WmHintsSet(w.X, w.Id, &icccm.Hints{ + Flags: curFlags | icccm.HintInput, + Input: 1, + }) + + // Get the current protocols so we don't overwrite anything. + prots, _ := icccm.WmProtocolsGet(w.X, w.Id) + + // If WM_TAKE_FOCUS isn't here, add it. Otherwise, move on. + wmfocus := false + for _, prot := range prots { + if prot == "WM_TAKE_FOCUS" { + wmfocus = true + break + } + } + if !wmfocus { + icccm.WmProtocolsSet(w.X, w.Id, append(prots, "WM_TAKE_FOCUS")) + } + + // Attach a ClientMessage event handler. It will determine whether the + // ClientMessage is a 'focus' request, and if so, run the callback 'cb' + // provided. + xevent.ClientMessageFun( + func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { + if icccm.IsFocusProtocol(X, ev) { + cb(w, xproto.Timestamp(ev.Data.Data32[1])) + } + }).Connect(w.X, w.Id) +} diff --git a/vend/xgbutil/xwindow/xwindow.go b/vend/xgbutil/xwindow/xwindow.go new file mode 100644 index 0000000..d250ae1 --- /dev/null +++ b/vend/xgbutil/xwindow/xwindow.go @@ -0,0 +1,393 @@ +package xwindow + +import ( + "fmt" + + "github.com/jezek/xgb/xproto" + + "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/keybind" + "github.com/jezek/xgbutil/mousebind" + "github.com/jezek/xgbutil/xevent" + "github.com/jezek/xgbutil/xrect" +) + +// Window represents an X window. It contains an XUtilValue to simplfy the +// parameter lists for methods declared on the Window type. +// Geom is updated whenever Geometry is called, or when Move, Resize or +// MoveResize are called. +type Window struct { + X *xgbutil.XUtil + Id xproto.Window + Geom xrect.Rect + Destroyed bool +} + +// New creates a new window value from a window id and an XUtil type. +// Geom is initialized to zero values. Use Window.Geometry to load it. +// Note that the geometry is the size of this particular window and nothing +// else. If you want the geometry of a client window including decorations, +// please use Window.DecorGeometry. +func New(xu *xgbutil.XUtil, win xproto.Window) *Window { + return &Window{ + X: xu, + Id: win, + Geom: xrect.New(0, 0, 1, 1), + Destroyed: false, + } +} + +// Generate is just like New, but generates a new X resource id for you. +// Geom is initialized to (0, 0) 1x1. +// It is possible for id generation to return an error, in which case, an +// error is returned here. +func Generate(xu *xgbutil.XUtil) (*Window, error) { + wid, err := xproto.NewWindowId(xu.Conn()) + if err != nil { + return nil, err + } + return New(xu, wid), nil +} + +// Create is a convenience constructor that will generate a new window id (with +// the Generate constructor) and make a bare-bones call to CreateChecked (with +// geometry (0, 0) 1x1). An error can be generated from Generate or +// CreateChecked. +func Create(xu *xgbutil.XUtil, parent xproto.Window) (*Window, error) { + win, err := Generate(xu) + if err != nil { + return nil, err + } + + err = win.CreateChecked(parent, 0, 0, 1, 1, 0) + if err != nil { + return nil, err + } + + return win, nil +} + +// Must panics if err is non-nil or if win is nil. Otherwise, win is returned. +func Must(win *Window, err error) *Window { + if err != nil { + panic(err) + } + if win == nil { + panic("win and err are nil") + } + return win +} + +// Create issues a CreateWindow request for Window. +// Its purpose is to omit several boiler-plate parameters to CreateWindow +// and expose the commonly useful ones. +// The value mask describes which values are present in valueList. +// Value masks can be found in xgb/xproto with the prefix 'Cw'. +// The value list must contain values in the same order as the constants +// are defined in xgb/xproto. +// +// For example, the following creates a window positioned at (20, 50) with +// width 500 and height 700 with a background color of white. +// +// w, err := xwindow.Generate(X) +// if err != nil { +// log.Fatalf("Could not generate a new resource identifier: %s", err) +// } +// w.Create(X.RootWin(), 20, 50, 500, 700, +// xproto.CwBackPixel, 0xffffff) +func (w *Window) Create(parent xproto.Window, x, y, width, height, + valueMask int, valueList ...uint32) { + + s := w.X.Screen() + xproto.CreateWindow(w.X.Conn(), + xproto.WindowClassCopyFromParent, w.Id, parent, + int16(x), int16(y), uint16(width), uint16(height), 0, + xproto.WindowClassInputOutput, s.RootVisual, + uint32(valueMask), valueList) +} + +// CreateChecked issues a CreateWindow checked request for Window. +// A checked request is a synchronous request. Meaning that if the request +// fails, you can get the error returned to you. However, it also forced your +// program to block for a round trip to the X server, so it is slower. +// See the docs for Create for more info. +func (w *Window) CreateChecked(parent xproto.Window, x, y, width, height, + valueMask int, valueList ...uint32) error { + + s := w.X.Screen() + return xproto.CreateWindowChecked(w.X.Conn(), + s.RootDepth, w.Id, parent, + int16(x), int16(y), uint16(width), uint16(height), 0, + xproto.WindowClassInputOutput, s.RootVisual, + uint32(valueMask), valueList).Check() +} + +// Change issues a ChangeWindowAttributes request with the provided mask +// and value list. Please see Window.Create for an example on how to use +// the mask and value list. +func (w *Window) Change(valueMask int, valueList ...uint32) { + xproto.ChangeWindowAttributes(w.X.Conn(), w.Id, + uint32(valueMask), valueList) +} + +// Listen will tell X to report events corresponding to the event masks +// provided for the given window. If a call to Listen is omitted, you will +// not receive the events you desire. +// Event masks are constants declare in the xgb/xproto package starting with the +// EventMask prefix. +func (w *Window) Listen(evMasks ...int) error { + evMask := 0 + for _, mask := range evMasks { + evMask |= mask + } + return xproto.ChangeWindowAttributesChecked(w.X.Conn(), w.Id, + xproto.CwEventMask, []uint32{uint32(evMask)}).Check() +} + +// Geometry retrieves an up-to-date version of the this window's geometry. +// It also loads the geometry into the Geom member of Window. +func (w *Window) Geometry() (xrect.Rect, error) { + geom, err := RawGeometry(w.X, xproto.Drawable(w.Id)) + if err != nil { + return nil, err + } + w.Geom = geom + return geom, err +} + +// RawGeometry isn't smart. It just queries the window given for geometry. +func RawGeometry(xu *xgbutil.XUtil, win xproto.Drawable) (xrect.Rect, error) { + xgeom, err := xproto.GetGeometry(xu.Conn(), win).Reply() + if err != nil { + return nil, err + } + return xrect.New(int(xgeom.X), int(xgeom.Y), + int(xgeom.Width), int(xgeom.Height)), nil +} + +// RootGeometry gets the geometry of the root window. It will panic on failure. +func RootGeometry(xu *xgbutil.XUtil) xrect.Rect { + geom, err := RawGeometry(xu, xproto.Drawable(xu.RootWin())) + if err != nil { + panic(err) + } + return geom +} + +// Configure issues a raw Configure request with the parameters given and +// updates the geometry of the window. +// This should probably only be used when passing along ConfigureNotify events +// (from the perspective of the window manager). In other cases, one should +// opt for [WM][Move][Resize] or Stack[Sibling]. +func (win *Window) Configure(flags, x, y, w, h int, + sibling xproto.Window, stackMode byte) { + + if win == nil { + return + } + + vals := []uint32{} + + if xproto.ConfigWindowX&flags > 0 { + vals = append(vals, uint32(x)) + win.Geom.XSet(x) + } + if xproto.ConfigWindowY&flags > 0 { + vals = append(vals, uint32(y)) + win.Geom.YSet(y) + } + if xproto.ConfigWindowWidth&flags > 0 { + if int16(w) <= 0 { + w = 1 + } + vals = append(vals, uint32(w)) + win.Geom.WidthSet(w) + } + if xproto.ConfigWindowHeight&flags > 0 { + if int16(h) <= 0 { + h = 1 + } + vals = append(vals, uint32(h)) + win.Geom.HeightSet(h) + } + if xproto.ConfigWindowSibling&flags > 0 { + vals = append(vals, uint32(sibling)) + } + if xproto.ConfigWindowStackMode&flags > 0 { + vals = append(vals, uint32(stackMode)) + } + + // Nobody should be setting border widths any more. + // We toss it out since `vals` must have length equal to the number + // of bits set in `flags`. + flags &= ^xproto.ConfigWindowBorderWidth + xproto.ConfigureWindow(win.X.Conn(), win.Id, uint16(flags), vals) +} + +// MROpt is like MoveResize, but exposes the X value mask so that any +// combination of x/y/width/height can be set. It's a strictly convenience +// function. (i.e., when you need to set 'y' and 'height' but not 'x' or +// 'width'.) +func (w *Window) MROpt(flags, x, y, width, height int) { + // Make sure only x/y/width/height are used. + flags &= xproto.ConfigWindowX | xproto.ConfigWindowY | + xproto.ConfigWindowWidth | xproto.ConfigWindowHeight + w.Configure(flags, x, y, width, height, 0, 0) +} + +// MoveResize issues a ConfigureRequest for this window with the provided +// x, y, width and height. Note that if width or height is 0, X will stomp +// all over you. Really hard. Don't do it. +// If you're trying to move/resize a top-level window in a window manager that +// supports EWMH, please use WMMoveResize instead. +func (w *Window) MoveResize(x, y, width, height int) { + w.Configure(xproto.ConfigWindowX|xproto.ConfigWindowY| + xproto.ConfigWindowWidth|xproto.ConfigWindowHeight, x, y, width, height, + 0, 0) +} + +// Move issues a ConfigureRequest for this window with the provided +// x and y positions. +// If you're trying to move a top-level window in a window manager that +// supports EWMH, please use WMMove instead. +func (w *Window) Move(x, y int) { + w.Configure(xproto.ConfigWindowX|xproto.ConfigWindowY, x, y, 0, 0, 0, 0) +} + +// Resize issues a ConfigureRequest for this window with the provided +// width and height. Note that if width or height is 0, X will stomp +// all over you. Really hard. Don't do it. +// If you're trying to resize a top-level window in a window manager that +// supports EWMH, please use WMResize instead. +func (w *Window) Resize(width, height int) { + w.Configure(xproto.ConfigWindowWidth|xproto.ConfigWindowHeight, 0, 0, + width, height, 0, 0) +} + +// Stack issues a configure request to change the stack mode of Window. +// If you're using a window manager that supports EWMH, you may want to try +// and use ewmh.RestackWindow instead. Although this should still work. +// 'mode' values can be found as constants in xgb/xproto with the prefix +// StackMode. +// A value of xproto.StackModeAbove will put the window to the top of the stack, +// while a value of xproto.StackMoveBelow will put the window to the +// bottom of the stack. +// Remember that stacking is at the discretion of the window manager, and +// therefore may not always work as one would expect. +func (w *Window) Stack(mode byte) { + xproto.ConfigureWindow(w.X.Conn(), w.Id, + xproto.ConfigWindowStackMode, []uint32{uint32(mode)}) +} + +// StackSibling issues a configure request to change the sibling and stack mode +// of Window. +// If you're using a window manager that supports EWMH, you may want to try +// and use ewmh.RestackWindowExtra instead. Although this should still work. +// 'mode' values can be found as constants in xgb/xproto with the prefix +// StackMode. +// 'sibling' refers to the sibling window in the stacking order through which +// 'mode' is interpreted. Note that 'sibling' should be taken literally. A +// window can only be stacked with respect to a *sibling* in the window tree. +// This means that a client window that has been wrapped in decorations cannot +// be stacked with respect to another client window. (This is why you should +// use ewmh.RestackWindowExtra instead.) +func (w *Window) StackSibling(sibling xproto.Window, mode byte) { + xproto.ConfigureWindow(w.X.Conn(), w.Id, + xproto.ConfigWindowSibling|xproto.ConfigWindowStackMode, + []uint32{uint32(sibling), uint32(mode)}) +} + +// Map is a simple alias to map the window. +func (w *Window) Map() { + if w == nil { + return + } + + xproto.MapWindow(w.X.Conn(), w.Id) +} + +// Unmap is a simple alias to unmap the window. +func (w *Window) Unmap() { + if w == nil { + return + } + + xproto.UnmapWindow(w.X.Conn(), w.Id) +} + +// Destroy is a simple alias to destroy a window. You should use this when +// you no longer intend to use this window. (It will free the X resource +// identifier for use in other places.) +func (w *Window) Destroy() { + if !w.Destroyed { + w.Detach() + err := xproto.DestroyWindowChecked(w.X.Conn(), w.Id).Check() + if err != nil { + xgbutil.Logger.Println(err) + } + + w.Destroyed = true + } +} + +// Detach will detach this window's event handlers from all xevent, keybind +// and mousebind callbacks. +func (w *Window) Detach() { + keybind.Detach(w.X, w.Id) + mousebind.Detach(w.X, w.Id) + xevent.Detach(w.X, w.Id) +} + +// Focus tries to issue a SetInputFocus to get the focus. +// If you're trying to change the top-level active window, please use +// ewmh.ActiveWindowReq instead. +func (w *Window) Focus() { + mode := byte(xproto.InputFocusPointerRoot) + err := xproto.SetInputFocusChecked(w.X.Conn(), mode, w.Id, 0).Check() + if err != nil { + xgbutil.Logger.Println(err) + } +} + +// FocusParent is just like Focus, except it sets the "revert-to" mode to +// Parent. This should be used when setting focus to a sub-window. +func (w *Window) FocusParent(tstamp xproto.Timestamp) { + mode := byte(xproto.InputFocusParent) + err := xproto.SetInputFocusChecked(w.X.Conn(), mode, w.Id, tstamp).Check() + if err != nil { + xgbutil.Logger.Println(err) + } +} + +// Kill forcefully destroys a client. It is almost never what you want, and if +// you do it to one your clients, you'll lose your connection. +// (This is typically used in a special client like `xkill` or in a window +// manager.) +func (w *Window) Kill() { + xproto.KillClient(w.X.Conn(), uint32(w.Id)) +} + +// Clear paints the region of the window specified with the corresponding +// background pixmap. If the window doesn't have a background pixmap, +// this has no effect. +// If width/height is 0, then it is set to the width/height of the background +// pixmap minus x/y. +func (w *Window) Clear(x, y, width, height int) { + xproto.ClearArea(w.X.Conn(), false, w.Id, + int16(x), int16(y), uint16(width), uint16(height)) +} + +// ClearAll is the same as Clear, but does it for the entire background pixmap. +func (w *Window) ClearAll() { + xproto.ClearArea(w.X.Conn(), false, w.Id, 0, 0, 0, 0) +} + +// Parent queries the QueryTree and finds the parent window. +func (w *Window) Parent() (*Window, error) { + tree, err := xproto.QueryTree(w.X.Conn(), w.Id).Reply() + if err != nil { + return nil, fmt.Errorf("ParentWindow: Error retrieving parent window "+ + "for %x: %s", w.Id, err) + } + return New(w.X, tree.Parent), nil +} diff --git a/xgb b/xgb deleted file mode 160000 index a57abb5..0000000 --- a/xgb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a57abb570aeba12f867c58afe22ce49ac5db4872 diff --git a/xgbutil b/xgbutil deleted file mode 160000 index 04188eb..0000000 --- a/xgbutil +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 04188eb39cf0fa005f5b3aec48faa82541748b79