aboutsummaryrefslogtreecommitdiff
path: root/nexgb/bigreq/bigreq.go
blob: 237e6f3eb777f2e5ad8941cbbb6d136c818e3c05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// 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 (
	xgb "janouch.name/haven/nexgb"

	"janouch.name/haven/nexgb/xproto"
)

const (
	MajorVersion = 0
	MinorVersion = 0
)

// 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
}

// enableRequest writes a Enable request to a byte slice for transfer.
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
}