1
2 package xtest
3
4
5
6 import (
7 "github.com/jezek/xgb"
8
9 "github.com/jezek/xgb/xproto"
10 )
11
12
13 func Init(c *xgb.Conn) error {
14 reply, err := xproto.QueryExtension(c, 5, "XTEST").Reply()
15 switch {
16 case err != nil:
17 return err
18 case !reply.Present:
19 return xgb.Errorf("No extension named XTEST could be found on on the server.")
20 }
21
22 c.ExtLock.Lock()
23 c.Extensions["XTEST"] = reply.MajorOpcode
24 c.ExtLock.Unlock()
25 for evNum, fun := range xgb.NewExtEventFuncs["XTEST"] {
26 xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun
27 }
28 for errNum, fun := range xgb.NewExtErrorFuncs["XTEST"] {
29 xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun
30 }
31 return nil
32 }
33
34 func init() {
35 xgb.NewExtEventFuncs["XTEST"] = make(map[int]xgb.NewEventFun)
36 xgb.NewExtErrorFuncs["XTEST"] = make(map[int]xgb.NewErrorFun)
37 }
38
39 const (
40 CursorNone = 0
41 CursorCurrent = 1
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 type CompareCursorCookie struct {
70 *xgb.Cookie
71 }
72
73
74
75 func CompareCursor(c *xgb.Conn, Window xproto.Window, Cursor xproto.Cursor) CompareCursorCookie {
76 c.ExtLock.RLock()
77 defer c.ExtLock.RUnlock()
78 if _, ok := c.Extensions["XTEST"]; !ok {
79 panic("Cannot issue request 'CompareCursor' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
80 }
81 cookie := c.NewCookie(true, true)
82 c.NewRequest(compareCursorRequest(c, Window, Cursor), cookie)
83 return CompareCursorCookie{cookie}
84 }
85
86
87
88 func CompareCursorUnchecked(c *xgb.Conn, Window xproto.Window, Cursor xproto.Cursor) CompareCursorCookie {
89 c.ExtLock.RLock()
90 defer c.ExtLock.RUnlock()
91 if _, ok := c.Extensions["XTEST"]; !ok {
92 panic("Cannot issue request 'CompareCursor' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
93 }
94 cookie := c.NewCookie(false, true)
95 c.NewRequest(compareCursorRequest(c, Window, Cursor), cookie)
96 return CompareCursorCookie{cookie}
97 }
98
99
100 type CompareCursorReply struct {
101 Sequence uint16
102 Length uint32
103 Same bool
104 }
105
106
107 func (cook CompareCursorCookie) Reply() (*CompareCursorReply, error) {
108 buf, err := cook.Cookie.Reply()
109 if err != nil {
110 return nil, err
111 }
112 if buf == nil {
113 return nil, nil
114 }
115 return compareCursorReply(buf), nil
116 }
117
118
119 func compareCursorReply(buf []byte) *CompareCursorReply {
120 v := new(CompareCursorReply)
121 b := 1
122
123 if buf[b] == 1 {
124 v.Same = true
125 } else {
126 v.Same = false
127 }
128 b += 1
129
130 v.Sequence = xgb.Get16(buf[b:])
131 b += 2
132
133 v.Length = xgb.Get32(buf[b:])
134 b += 4
135
136 return v
137 }
138
139
140
141 func compareCursorRequest(c *xgb.Conn, Window xproto.Window, Cursor xproto.Cursor) []byte {
142 size := 12
143 b := 0
144 buf := make([]byte, size)
145
146 c.ExtLock.RLock()
147 buf[b] = c.Extensions["XTEST"]
148 c.ExtLock.RUnlock()
149 b += 1
150
151 buf[b] = 1
152 b += 1
153
154 xgb.Put16(buf[b:], uint16(size/4))
155 b += 2
156
157 xgb.Put32(buf[b:], uint32(Window))
158 b += 4
159
160 xgb.Put32(buf[b:], uint32(Cursor))
161 b += 4
162
163 return buf
164 }
165
166
167 type FakeInputCookie struct {
168 *xgb.Cookie
169 }
170
171
172
173 func FakeInput(c *xgb.Conn, Type byte, Detail byte, Time uint32, Root xproto.Window, RootX int16, RootY int16, Deviceid byte) FakeInputCookie {
174 c.ExtLock.RLock()
175 defer c.ExtLock.RUnlock()
176 if _, ok := c.Extensions["XTEST"]; !ok {
177 panic("Cannot issue request 'FakeInput' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
178 }
179 cookie := c.NewCookie(false, false)
180 c.NewRequest(fakeInputRequest(c, Type, Detail, Time, Root, RootX, RootY, Deviceid), cookie)
181 return FakeInputCookie{cookie}
182 }
183
184
185
186 func FakeInputChecked(c *xgb.Conn, Type byte, Detail byte, Time uint32, Root xproto.Window, RootX int16, RootY int16, Deviceid byte) FakeInputCookie {
187 c.ExtLock.RLock()
188 defer c.ExtLock.RUnlock()
189 if _, ok := c.Extensions["XTEST"]; !ok {
190 panic("Cannot issue request 'FakeInput' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
191 }
192 cookie := c.NewCookie(true, false)
193 c.NewRequest(fakeInputRequest(c, Type, Detail, Time, Root, RootX, RootY, Deviceid), cookie)
194 return FakeInputCookie{cookie}
195 }
196
197
198
199 func (cook FakeInputCookie) Check() error {
200 return cook.Cookie.Check()
201 }
202
203
204
205 func fakeInputRequest(c *xgb.Conn, Type byte, Detail byte, Time uint32, Root xproto.Window, RootX int16, RootY int16, Deviceid byte) []byte {
206 size := 36
207 b := 0
208 buf := make([]byte, size)
209
210 c.ExtLock.RLock()
211 buf[b] = c.Extensions["XTEST"]
212 c.ExtLock.RUnlock()
213 b += 1
214
215 buf[b] = 2
216 b += 1
217
218 xgb.Put16(buf[b:], uint16(size/4))
219 b += 2
220
221 buf[b] = Type
222 b += 1
223
224 buf[b] = Detail
225 b += 1
226
227 b += 2
228
229 xgb.Put32(buf[b:], Time)
230 b += 4
231
232 xgb.Put32(buf[b:], uint32(Root))
233 b += 4
234
235 b += 8
236
237 xgb.Put16(buf[b:], uint16(RootX))
238 b += 2
239
240 xgb.Put16(buf[b:], uint16(RootY))
241 b += 2
242
243 b += 7
244
245 buf[b] = Deviceid
246 b += 1
247
248 return buf
249 }
250
251
252 type GetVersionCookie struct {
253 *xgb.Cookie
254 }
255
256
257
258 func GetVersion(c *xgb.Conn, MajorVersion byte, MinorVersion uint16) GetVersionCookie {
259 c.ExtLock.RLock()
260 defer c.ExtLock.RUnlock()
261 if _, ok := c.Extensions["XTEST"]; !ok {
262 panic("Cannot issue request 'GetVersion' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
263 }
264 cookie := c.NewCookie(true, true)
265 c.NewRequest(getVersionRequest(c, MajorVersion, MinorVersion), cookie)
266 return GetVersionCookie{cookie}
267 }
268
269
270
271 func GetVersionUnchecked(c *xgb.Conn, MajorVersion byte, MinorVersion uint16) GetVersionCookie {
272 c.ExtLock.RLock()
273 defer c.ExtLock.RUnlock()
274 if _, ok := c.Extensions["XTEST"]; !ok {
275 panic("Cannot issue request 'GetVersion' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
276 }
277 cookie := c.NewCookie(false, true)
278 c.NewRequest(getVersionRequest(c, MajorVersion, MinorVersion), cookie)
279 return GetVersionCookie{cookie}
280 }
281
282
283 type GetVersionReply struct {
284 Sequence uint16
285 Length uint32
286 MajorVersion byte
287 MinorVersion uint16
288 }
289
290
291 func (cook GetVersionCookie) Reply() (*GetVersionReply, error) {
292 buf, err := cook.Cookie.Reply()
293 if err != nil {
294 return nil, err
295 }
296 if buf == nil {
297 return nil, nil
298 }
299 return getVersionReply(buf), nil
300 }
301
302
303 func getVersionReply(buf []byte) *GetVersionReply {
304 v := new(GetVersionReply)
305 b := 1
306
307 v.MajorVersion = buf[b]
308 b += 1
309
310 v.Sequence = xgb.Get16(buf[b:])
311 b += 2
312
313 v.Length = xgb.Get32(buf[b:])
314 b += 4
315
316 v.MinorVersion = xgb.Get16(buf[b:])
317 b += 2
318
319 return v
320 }
321
322
323
324 func getVersionRequest(c *xgb.Conn, MajorVersion byte, MinorVersion uint16) []byte {
325 size := 8
326 b := 0
327 buf := make([]byte, size)
328
329 c.ExtLock.RLock()
330 buf[b] = c.Extensions["XTEST"]
331 c.ExtLock.RUnlock()
332 b += 1
333
334 buf[b] = 0
335 b += 1
336
337 xgb.Put16(buf[b:], uint16(size/4))
338 b += 2
339
340 buf[b] = MajorVersion
341 b += 1
342
343 b += 1
344
345 xgb.Put16(buf[b:], MinorVersion)
346 b += 2
347
348 return buf
349 }
350
351
352 type GrabControlCookie struct {
353 *xgb.Cookie
354 }
355
356
357
358 func GrabControl(c *xgb.Conn, Impervious bool) GrabControlCookie {
359 c.ExtLock.RLock()
360 defer c.ExtLock.RUnlock()
361 if _, ok := c.Extensions["XTEST"]; !ok {
362 panic("Cannot issue request 'GrabControl' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
363 }
364 cookie := c.NewCookie(false, false)
365 c.NewRequest(grabControlRequest(c, Impervious), cookie)
366 return GrabControlCookie{cookie}
367 }
368
369
370
371 func GrabControlChecked(c *xgb.Conn, Impervious bool) GrabControlCookie {
372 c.ExtLock.RLock()
373 defer c.ExtLock.RUnlock()
374 if _, ok := c.Extensions["XTEST"]; !ok {
375 panic("Cannot issue request 'GrabControl' using the uninitialized extension 'XTEST'. xtest.Init(connObj) must be called first.")
376 }
377 cookie := c.NewCookie(true, false)
378 c.NewRequest(grabControlRequest(c, Impervious), cookie)
379 return GrabControlCookie{cookie}
380 }
381
382
383
384 func (cook GrabControlCookie) Check() error {
385 return cook.Cookie.Check()
386 }
387
388
389
390 func grabControlRequest(c *xgb.Conn, Impervious bool) []byte {
391 size := 8
392 b := 0
393 buf := make([]byte, size)
394
395 c.ExtLock.RLock()
396 buf[b] = c.Extensions["XTEST"]
397 c.ExtLock.RUnlock()
398 b += 1
399
400 buf[b] = 3
401 b += 1
402
403 xgb.Put16(buf[b:], uint16(size/4))
404 b += 2
405
406 if Impervious {
407 buf[b] = 1
408 } else {
409 buf[b] = 0
410 }
411 b += 1
412
413 b += 3
414
415 return buf
416 }
417
View as plain text