github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/xtest/xtest.go (about) 1 // Package xtest is the X client API for the XTEST extension. 2 package xtest 3 4 // This file is automatically generated from xtest.xml. Edit at your peril! 5 6 import ( 7 "github.com/BurntSushi/xgb" 8 9 "github.com/BurntSushi/xgb/xproto" 10 ) 11 12 // Init must be called before using the XTEST extension. 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 // Skipping definition for base type 'Bool' 45 46 // Skipping definition for base type 'Byte' 47 48 // Skipping definition for base type 'Card8' 49 50 // Skipping definition for base type 'Char' 51 52 // Skipping definition for base type 'Void' 53 54 // Skipping definition for base type 'Double' 55 56 // Skipping definition for base type 'Float' 57 58 // Skipping definition for base type 'Int16' 59 60 // Skipping definition for base type 'Int32' 61 62 // Skipping definition for base type 'Int8' 63 64 // Skipping definition for base type 'Card16' 65 66 // Skipping definition for base type 'Card32' 67 68 // CompareCursorCookie is a cookie used only for CompareCursor requests. 69 type CompareCursorCookie struct { 70 *xgb.Cookie 71 } 72 73 // CompareCursor sends a checked request. 74 // If an error occurs, it will be returned with the reply by calling CompareCursorCookie.Reply() 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 // CompareCursorUnchecked sends an unchecked request. 87 // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. 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 // CompareCursorReply represents the data returned from a CompareCursor request. 100 type CompareCursorReply struct { 101 Sequence uint16 // sequence number of the request for this reply 102 Length uint32 // number of bytes in this reply 103 Same bool 104 } 105 106 // Reply blocks and returns the reply data for a CompareCursor request. 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 // compareCursorReply reads a byte slice into a CompareCursorReply value. 119 func compareCursorReply(buf []byte) *CompareCursorReply { 120 v := new(CompareCursorReply) 121 b := 1 // skip reply determinant 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:]) // 4-byte units 134 b += 4 135 136 return v 137 } 138 139 // Write request to wire for CompareCursor 140 // compareCursorRequest writes a CompareCursor request to a byte slice. 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 // request opcode 152 b += 1 153 154 xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units 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 // FakeInputCookie is a cookie used only for FakeInput requests. 167 type FakeInputCookie struct { 168 *xgb.Cookie 169 } 170 171 // FakeInput sends an unchecked request. 172 // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. 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 // FakeInputChecked sends a checked request. 185 // If an error occurs, it can be retrieved using FakeInputCookie.Check() 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 // Check returns an error if one occurred for checked requests that are not expecting a reply. 198 // This cannot be called for requests expecting a reply, nor for unchecked requests. 199 func (cook FakeInputCookie) Check() error { 200 return cook.Cookie.Check() 201 } 202 203 // Write request to wire for FakeInput 204 // fakeInputRequest writes a FakeInput request to a byte slice. 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 // request opcode 216 b += 1 217 218 xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units 219 b += 2 220 221 buf[b] = Type 222 b += 1 223 224 buf[b] = Detail 225 b += 1 226 227 b += 2 // padding 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 // padding 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 // padding 244 245 buf[b] = Deviceid 246 b += 1 247 248 return buf 249 } 250 251 // GetVersionCookie is a cookie used only for GetVersion requests. 252 type GetVersionCookie struct { 253 *xgb.Cookie 254 } 255 256 // GetVersion sends a checked request. 257 // If an error occurs, it will be returned with the reply by calling GetVersionCookie.Reply() 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 // GetVersionUnchecked sends an unchecked request. 270 // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. 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 // GetVersionReply represents the data returned from a GetVersion request. 283 type GetVersionReply struct { 284 Sequence uint16 // sequence number of the request for this reply 285 Length uint32 // number of bytes in this reply 286 MajorVersion byte 287 MinorVersion uint16 288 } 289 290 // Reply blocks and returns the reply data for a GetVersion request. 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 // getVersionReply reads a byte slice into a GetVersionReply value. 303 func getVersionReply(buf []byte) *GetVersionReply { 304 v := new(GetVersionReply) 305 b := 1 // skip reply determinant 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:]) // 4-byte units 314 b += 4 315 316 v.MinorVersion = xgb.Get16(buf[b:]) 317 b += 2 318 319 return v 320 } 321 322 // Write request to wire for GetVersion 323 // getVersionRequest writes a GetVersion request to a byte slice. 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 // request opcode 335 b += 1 336 337 xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units 338 b += 2 339 340 buf[b] = MajorVersion 341 b += 1 342 343 b += 1 // padding 344 345 xgb.Put16(buf[b:], MinorVersion) 346 b += 2 347 348 return buf 349 } 350 351 // GrabControlCookie is a cookie used only for GrabControl requests. 352 type GrabControlCookie struct { 353 *xgb.Cookie 354 } 355 356 // GrabControl sends an unchecked request. 357 // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. 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 // GrabControlChecked sends a checked request. 370 // If an error occurs, it can be retrieved using GrabControlCookie.Check() 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 // Check returns an error if one occurred for checked requests that are not expecting a reply. 383 // This cannot be called for requests expecting a reply, nor for unchecked requests. 384 func (cook GrabControlCookie) Check() error { 385 return cook.Cookie.Check() 386 } 387 388 // Write request to wire for GrabControl 389 // grabControlRequest writes a GrabControl request to a byte slice. 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 // request opcode 401 b += 1 402 403 xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units 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 // padding 414 415 return buf 416 }