From fd30f1512a713ae5b3cbacddfe9f29dfccc82047 Mon Sep 17 00:00:00 2001 From: "Andrew Gallant (Ocelot)" Date: Mon, 7 May 2012 01:00:45 -0400 Subject: [PATCH] added tests --- nexgb/Makefile | 6 + nexgb/auto_bigreq.go | 26 ++- nexgb/auto_composite.go | 38 +++- nexgb/auto_damage.go | 36 +++- nexgb/auto_dpms.go | 30 +++- nexgb/auto_dri2.go | 30 +++- nexgb/auto_ge.go | 34 +++- nexgb/auto_glx.go | 40 ++++- nexgb/auto_randr.go | 38 +++- nexgb/auto_record.go | 38 +++- nexgb/auto_render.go | 38 +++- nexgb/auto_res.go | 42 ++++- nexgb/auto_screensaver.go | 52 ++++-- nexgb/auto_shape.go | 28 ++- nexgb/auto_shm.go | 36 +++- nexgb/auto_sync.go | 30 +++- nexgb/auto_xc_misc.go | 42 ++++- nexgb/auto_xevie.go | 30 +++- nexgb/auto_xf86dri.go | 26 ++- nexgb/auto_xf86vidmode.go | 28 ++- nexgb/auto_xfixes.go | 30 +++- nexgb/auto_xinerama.go | 50 ++++-- nexgb/auto_xinput.go | 82 ++++++--- nexgb/auto_xprint.go | 42 ++++- nexgb/auto_xproto.go | 10 +- nexgb/auto_xselinux.go | 50 ++++-- nexgb/auto_xtest.go | 46 +++-- nexgb/auto_xv.go | 36 +++- nexgb/auto_xvmc.go | 38 +++- nexgb/cookie.go | 13 +- nexgb/xgb.go | 98 +++++------ nexgb/xgb_help.go | 7 + nexgb/xgb_test.go | 358 ++++++++++++++++++++++++++++++++++++++ 33 files changed, 1264 insertions(+), 264 deletions(-) create mode 100644 nexgb/xgb_test.go diff --git a/nexgb/Makefile b/nexgb/Makefile index b1ef0ca..c70b01c 100644 --- a/nexgb/Makefile +++ b/nexgb/Makefile @@ -14,3 +14,9 @@ all: bigreq.xml composite.xml damage.xml dpms.xml dri2.xml \ %.xml: xgbgen/xgbgen --proto-path $(XPROTO) $(XPROTO)/$*.xml > auto_$*.go +test: + go test + +bench: + go test -run 'nomatch' -bench '.*' -cpu 1,2,6 + diff --git a/nexgb/auto_bigreq.go b/nexgb/auto_bigreq.go index d008bce..3389470 100644 --- a/nexgb/auto_bigreq.go +++ b/nexgb/auto_bigreq.go @@ -1,10 +1,34 @@ package xgb /* - This file was generated by bigreq.xml on May 6 2012 3:00:43am EDT. + This file was generated by bigreq.xml on May 6 2012 5:48:46pm EDT. This file is automatically generated. Edit at your peril! */ +// BigreqInit must be called before using the BIG-REQUESTS extension. +func (c *Conn) BigreqInit() error { + reply, err := c.QueryExtension(12, "BIG-REQUESTS").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named BIG-REQUESTS could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["BIG-REQUESTS"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["BIG-REQUESTS"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["BIG-REQUESTS"] = make(map[int]newEventFun) +} + // Skipping definition for base type 'Float' // Skipping definition for base type 'Id' diff --git a/nexgb/auto_composite.go b/nexgb/auto_composite.go index 185e425..aec15c9 100644 --- a/nexgb/auto_composite.go +++ b/nexgb/auto_composite.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by composite.xml on May 6 2012 3:00:43am EDT. + This file was generated by composite.xml on May 6 2012 5:48:46pm EDT. This file is automatically generated. Edit at your peril! */ @@ -10,15 +10,29 @@ package xgb // import "xproto" // import "xfixes" -// Skipping definition for base type 'Float' +// CompositeInit must be called before using the Composite extension. +func (c *Conn) CompositeInit() error { + reply, err := c.QueryExtension(9, "Composite").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named Composite could be found on on the server.") + } -// Skipping definition for base type 'Id' + c.extLock.Lock() + c.extensions["Composite"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["Composite"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Card8' + return nil +} -// Skipping definition for base type 'Int16' - -// Skipping definition for base type 'Int32' +func init() { + newExtEventFuncs["Composite"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Void' @@ -36,6 +50,16 @@ package xgb // Skipping definition for base type 'Bool' +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Id' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + const ( CompositeRedirectAutomatic = 0 CompositeRedirectManual = 1 diff --git a/nexgb/auto_damage.go b/nexgb/auto_damage.go index c875016..8339e6a 100644 --- a/nexgb/auto_damage.go +++ b/nexgb/auto_damage.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by damage.xml on May 6 2012 3:00:43am EDT. + This file was generated by damage.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -10,13 +10,29 @@ package xgb // import "xproto" // import "xfixes" -// Skipping definition for base type 'Card16' +// DamageInit must be called before using the DAMAGE extension. +func (c *Conn) DamageInit() error { + reply, err := c.QueryExtension(6, "DAMAGE").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named DAMAGE could be found on on the server.") + } -// Skipping definition for base type 'Char' + c.extLock.Lock() + c.extensions["DAMAGE"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["DAMAGE"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Card32' + return nil +} -// Skipping definition for base type 'Double' +func init() { + newExtEventFuncs["DAMAGE"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Bool' @@ -36,6 +52,14 @@ package xgb // Skipping definition for base type 'Int8' +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Card32' + +// Skipping definition for base type 'Double' + const ( DamageReportLevelRawRectangles = 0 DamageReportLevelDeltaRectangles = 1 @@ -144,7 +168,7 @@ func (v DamageNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewDamageNotifyEvent + newExtEventFuncs["DAMAGE"][0] = NewDamageNotifyEvent } // Error definition DamageBadDamage (0) diff --git a/nexgb/auto_dpms.go b/nexgb/auto_dpms.go index a1f733b..eee6688 100644 --- a/nexgb/auto_dpms.go +++ b/nexgb/auto_dpms.go @@ -1,10 +1,36 @@ package xgb /* - This file was generated by dpms.xml on May 6 2012 3:00:44am EDT. + This file was generated by dpms.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ +// DpmsInit must be called before using the DPMS extension. +func (c *Conn) DpmsInit() error { + reply, err := c.QueryExtension(4, "DPMS").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named DPMS could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["DPMS"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["DPMS"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["DPMS"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Int32' + // Skipping definition for base type 'Void' // Skipping definition for base type 'Byte' @@ -29,8 +55,6 @@ package xgb // Skipping definition for base type 'Int16' -// Skipping definition for base type 'Int32' - const ( DpmsDPMSModeOn = 0 DpmsDPMSModeStandby = 1 diff --git a/nexgb/auto_dri2.go b/nexgb/auto_dri2.go index 7797623..0712891 100644 --- a/nexgb/auto_dri2.go +++ b/nexgb/auto_dri2.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by dri2.xml on May 6 2012 3:00:44am EDT. + This file was generated by dri2.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,30 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// Dri2Init must be called before using the DRI2 extension. +func (c *Conn) Dri2Init() error { + reply, err := c.QueryExtension(4, "DRI2").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named DRI2 could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["DRI2"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["DRI2"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["DRI2"] = make(map[int]newEventFun) +} + // Skipping definition for base type 'Float' // Skipping definition for base type 'Id' @@ -306,7 +330,7 @@ func (v Dri2BufferSwapCompleteEvent) String() string { } func init() { - newEventFuncs[0] = NewDri2BufferSwapCompleteEvent + newExtEventFuncs["DRI2"][0] = NewDri2BufferSwapCompleteEvent } // Event definition Dri2InvalidateBuffers (1) @@ -369,7 +393,7 @@ func (v Dri2InvalidateBuffersEvent) String() string { } func init() { - newEventFuncs[1] = NewDri2InvalidateBuffersEvent + newExtEventFuncs["DRI2"][1] = NewDri2InvalidateBuffersEvent } // Request Dri2QueryVersion diff --git a/nexgb/auto_ge.go b/nexgb/auto_ge.go index d9f52c1..9a06265 100644 --- a/nexgb/auto_ge.go +++ b/nexgb/auto_ge.go @@ -1,17 +1,33 @@ package xgb /* - This file was generated by ge.xml on May 6 2012 3:00:44am EDT. + This file was generated by ge.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ -// Skipping definition for base type 'Id' +// GeInit must be called before using the Generic Event Extension extension. +func (c *Conn) GeInit() error { + reply, err := c.QueryExtension(23, "Generic Event Extension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named Generic Event Extension could be found on on the server.") + } -// Skipping definition for base type 'Card8' + c.extLock.Lock() + c.extensions["Generic Event Extension"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["Generic Event Extension"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Int16' + return nil +} -// Skipping definition for base type 'Int32' +func init() { + newExtEventFuncs["Generic Event Extension"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Void' @@ -31,6 +47,14 @@ package xgb // Skipping definition for base type 'Float' +// Skipping definition for base type 'Id' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + // Request GeQueryVersion // size: 8 type GeQueryVersionCookie struct { diff --git a/nexgb/auto_glx.go b/nexgb/auto_glx.go index 4b6b2c5..1b88e6c 100644 --- a/nexgb/auto_glx.go +++ b/nexgb/auto_glx.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by glx.xml on May 6 2012 3:00:44am EDT. + This file was generated by glx.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,15 +9,29 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" -// Skipping definition for base type 'Card16' +// GlxInit must be called before using the GLX extension. +func (c *Conn) GlxInit() error { + reply, err := c.QueryExtension(3, "GLX").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named GLX could be found on on the server.") + } -// Skipping definition for base type 'Char' + c.extLock.Lock() + c.extensions["GLX"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["GLX"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Card32' + return nil +} -// Skipping definition for base type 'Double' - -// Skipping definition for base type 'Bool' +func init() { + newExtEventFuncs["GLX"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Float' @@ -35,6 +49,16 @@ package xgb // Skipping definition for base type 'Int8' +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Card32' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Bool' + const ( GlxPbcetDamaged = 32791 GlxPbcetSaved = 32792 @@ -232,7 +256,7 @@ func (v GlxPbufferClobberEvent) String() string { } func init() { - newEventFuncs[0] = NewGlxPbufferClobberEvent + newExtEventFuncs["GLX"][0] = NewGlxPbufferClobberEvent } // Error definition GlxGeneric (-1) diff --git a/nexgb/auto_randr.go b/nexgb/auto_randr.go index bb092f5..cc5e760 100644 --- a/nexgb/auto_randr.go +++ b/nexgb/auto_randr.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by randr.xml on May 6 2012 3:00:44am EDT. + This file was generated by randr.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -10,13 +10,29 @@ package xgb // import "xproto" // import "render" -// Skipping definition for base type 'Int32' +// RandrInit must be called before using the RANDR extension. +func (c *Conn) RandrInit() error { + reply, err := c.QueryExtension(5, "RANDR").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named RANDR could be found on on the server.") + } -// Skipping definition for base type 'Void' + c.extLock.Lock() + c.extensions["RANDR"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["RANDR"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Byte' + return nil +} -// Skipping definition for base type 'Int8' +func init() { + newExtEventFuncs["RANDR"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Card16' @@ -36,6 +52,14 @@ package xgb // Skipping definition for base type 'Int16' +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Int8' + const ( RandrRotationRotate0 = 1 RandrRotationRotate90 = 2 @@ -963,7 +987,7 @@ func (v RandrScreenChangeNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewRandrScreenChangeNotifyEvent + newExtEventFuncs["RANDR"][0] = NewRandrScreenChangeNotifyEvent } // Event definition RandrNotify (1) @@ -1031,7 +1055,7 @@ func (v RandrNotifyEvent) String() string { } func init() { - newEventFuncs[1] = NewRandrNotifyEvent + newExtEventFuncs["RANDR"][1] = NewRandrNotifyEvent } // Error definition RandrBadOutput (0) diff --git a/nexgb/auto_record.go b/nexgb/auto_record.go index 75caf76..6fb966b 100644 --- a/nexgb/auto_record.go +++ b/nexgb/auto_record.go @@ -1,10 +1,40 @@ package xgb /* - This file was generated by record.xml on May 6 2012 3:00:44am EDT. + This file was generated by record.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ +// RecordInit must be called before using the RECORD extension. +func (c *Conn) RecordInit() error { + reply, err := c.QueryExtension(6, "RECORD").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named RECORD could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["RECORD"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["RECORD"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["RECORD"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + // Skipping definition for base type 'Card32' // Skipping definition for base type 'Double' @@ -25,12 +55,6 @@ package xgb // Skipping definition for base type 'Byte' -// Skipping definition for base type 'Int8' - -// Skipping definition for base type 'Card16' - -// Skipping definition for base type 'Char' - const ( RecordHTypeFromServerTime = 1 RecordHTypeFromClientTime = 2 diff --git a/nexgb/auto_render.go b/nexgb/auto_render.go index f6b37b7..c9fc097 100644 --- a/nexgb/auto_render.go +++ b/nexgb/auto_render.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by render.xml on May 6 2012 3:00:44am EDT. + This file was generated by render.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,36 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// RenderInit must be called before using the RENDER extension. +func (c *Conn) RenderInit() error { + reply, err := c.QueryExtension(6, "RENDER").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named RENDER could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["RENDER"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["RENDER"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["RENDER"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Byte' + // Skipping definition for base type 'Int8' // Skipping definition for base type 'Card16' @@ -29,12 +59,6 @@ package xgb // Skipping definition for base type 'Int16' -// Skipping definition for base type 'Int32' - -// Skipping definition for base type 'Void' - -// Skipping definition for base type 'Byte' - const ( RenderPictTypeIndexed = 0 RenderPictTypeDirect = 1 diff --git a/nexgb/auto_res.go b/nexgb/auto_res.go index 066bad8..d3f0f0b 100644 --- a/nexgb/auto_res.go +++ b/nexgb/auto_res.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by res.xml on May 6 2012 3:00:44am EDT. + This file was generated by res.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,17 +9,29 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" -// Skipping definition for base type 'Card16' +// ResInit must be called before using the X-Resource extension. +func (c *Conn) ResInit() error { + reply, err := c.QueryExtension(10, "X-Resource").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named X-Resource could be found on on the server.") + } -// Skipping definition for base type 'Char' + c.extLock.Lock() + c.extensions["X-Resource"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["X-Resource"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Card32' + return nil +} -// Skipping definition for base type 'Double' - -// Skipping definition for base type 'Bool' - -// Skipping definition for base type 'Float' +func init() { + newExtEventFuncs["X-Resource"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Id' @@ -35,6 +47,18 @@ package xgb // Skipping definition for base type 'Int8' +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Card32' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Float' + // 'ResClient' struct definition // Size: 8 type ResClient struct { diff --git a/nexgb/auto_screensaver.go b/nexgb/auto_screensaver.go index c023eec..1e47b91 100644 --- a/nexgb/auto_screensaver.go +++ b/nexgb/auto_screensaver.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by screensaver.xml on May 6 2012 3:00:44am EDT. + This file was generated by screensaver.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,42 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// ScreensaverInit must be called before using the MIT-SCREEN-SAVER extension. +func (c *Conn) ScreensaverInit() error { + reply, err := c.QueryExtension(16, "MIT-SCREEN-SAVER").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named MIT-SCREEN-SAVER could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["MIT-SCREEN-SAVER"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["MIT-SCREEN-SAVER"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["MIT-SCREEN-SAVER"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + // Skipping definition for base type 'Char' // Skipping definition for base type 'Card32' @@ -23,18 +59,6 @@ package xgb // Skipping definition for base type 'Card8' -// Skipping definition for base type 'Int16' - -// Skipping definition for base type 'Int32' - -// Skipping definition for base type 'Void' - -// Skipping definition for base type 'Byte' - -// Skipping definition for base type 'Int8' - -// Skipping definition for base type 'Card16' - const ( ScreensaverKindBlanked = 0 ScreensaverKindInternal = 1 @@ -182,7 +206,7 @@ func (v ScreensaverNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewScreensaverNotifyEvent + newExtEventFuncs["MIT-SCREEN-SAVER"][0] = NewScreensaverNotifyEvent } // Request ScreensaverQueryVersion diff --git a/nexgb/auto_shape.go b/nexgb/auto_shape.go index b5c5f04..a28836c 100644 --- a/nexgb/auto_shape.go +++ b/nexgb/auto_shape.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by shape.xml on May 6 2012 3:00:44am EDT. + This file was generated by shape.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,30 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// ShapeInit must be called before using the SHAPE extension. +func (c *Conn) ShapeInit() error { + reply, err := c.QueryExtension(5, "SHAPE").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named SHAPE could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["SHAPE"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["SHAPE"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["SHAPE"] = make(map[int]newEventFun) +} + // Skipping definition for base type 'Card16' // Skipping definition for base type 'Char' @@ -177,7 +201,7 @@ func (v ShapeNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewShapeNotifyEvent + newExtEventFuncs["SHAPE"][0] = NewShapeNotifyEvent } // Request ShapeQueryVersion diff --git a/nexgb/auto_shm.go b/nexgb/auto_shm.go index 5b7ba28..514dc03 100644 --- a/nexgb/auto_shm.go +++ b/nexgb/auto_shm.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by shm.xml on May 6 2012 3:00:44am EDT. + This file was generated by shm.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,34 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// ShmInit must be called before using the MIT-SHM extension. +func (c *Conn) ShmInit() error { + reply, err := c.QueryExtension(7, "MIT-SHM").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named MIT-SHM could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["MIT-SHM"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["MIT-SHM"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["MIT-SHM"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Id' + // Skipping definition for base type 'Card8' // Skipping definition for base type 'Int16' @@ -31,10 +59,6 @@ package xgb // Skipping definition for base type 'Bool' -// Skipping definition for base type 'Float' - -// Skipping definition for base type 'Id' - // Skipping resource definition of 'Seg' // Event definition ShmCompletion (0) @@ -134,7 +158,7 @@ func (v ShmCompletionEvent) String() string { } func init() { - newEventFuncs[0] = NewShmCompletionEvent + newExtEventFuncs["MIT-SHM"][0] = NewShmCompletionEvent } // ErrorCopy definition ShmBadSeg (0) diff --git a/nexgb/auto_sync.go b/nexgb/auto_sync.go index e87c488..a59cf20 100644 --- a/nexgb/auto_sync.go +++ b/nexgb/auto_sync.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by sync.xml on May 6 2012 3:00:44am EDT. + This file was generated by sync.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,30 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// SyncInit must be called before using the SYNC extension. +func (c *Conn) SyncInit() error { + reply, err := c.QueryExtension(4, "SYNC").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named SYNC could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["SYNC"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["SYNC"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["SYNC"] = make(map[int]newEventFun) +} + // Skipping definition for base type 'Float' // Skipping definition for base type 'Id' @@ -465,7 +489,7 @@ func (v SyncCounterNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewSyncCounterNotifyEvent + newExtEventFuncs["SYNC"][0] = NewSyncCounterNotifyEvent } // Event definition SyncAlarmNotify (1) @@ -572,7 +596,7 @@ func (v SyncAlarmNotifyEvent) String() string { } func init() { - newEventFuncs[1] = NewSyncAlarmNotifyEvent + newExtEventFuncs["SYNC"][1] = NewSyncAlarmNotifyEvent } // Error definition SyncCounter (0) diff --git a/nexgb/auto_xc_misc.go b/nexgb/auto_xc_misc.go index 48a5d1e..66ad03a 100644 --- a/nexgb/auto_xc_misc.go +++ b/nexgb/auto_xc_misc.go @@ -1,21 +1,33 @@ package xgb /* - This file was generated by xc_misc.xml on May 6 2012 3:00:44am EDT. + This file was generated by xc_misc.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ -// Skipping definition for base type 'Float' +// Xc_miscInit must be called before using the XC-MISC extension. +func (c *Conn) Xc_miscInit() error { + reply, err := c.QueryExtension(7, "XC-MISC").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XC-MISC could be found on on the server.") + } -// Skipping definition for base type 'Id' + c.extLock.Lock() + c.extensions["XC-MISC"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XC-MISC"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Card8' + return nil +} -// Skipping definition for base type 'Int16' - -// Skipping definition for base type 'Int32' - -// Skipping definition for base type 'Void' +func init() { + newExtEventFuncs["XC-MISC"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Byte' @@ -31,6 +43,18 @@ package xgb // Skipping definition for base type 'Bool' +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Id' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + +// Skipping definition for base type 'Void' + // Request Xc_miscGetVersion // size: 8 type Xc_miscGetVersionCookie struct { diff --git a/nexgb/auto_xevie.go b/nexgb/auto_xevie.go index fbc1d92..eed775e 100644 --- a/nexgb/auto_xevie.go +++ b/nexgb/auto_xevie.go @@ -1,10 +1,36 @@ package xgb /* - This file was generated by xevie.xml on May 6 2012 3:00:44am EDT. + This file was generated by xevie.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ +// XevieInit must be called before using the XEVIE extension. +func (c *Conn) XevieInit() error { + reply, err := c.QueryExtension(5, "XEVIE").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XEVIE could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XEVIE"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XEVIE"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XEVIE"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Float' + // Skipping definition for base type 'Id' // Skipping definition for base type 'Card8' @@ -29,8 +55,6 @@ package xgb // Skipping definition for base type 'Bool' -// Skipping definition for base type 'Float' - const ( XevieDatatypeUnmodified = 0 XevieDatatypeModified = 1 diff --git a/nexgb/auto_xf86dri.go b/nexgb/auto_xf86dri.go index 1dbe77c..7407d24 100644 --- a/nexgb/auto_xf86dri.go +++ b/nexgb/auto_xf86dri.go @@ -1,10 +1,34 @@ package xgb /* - This file was generated by xf86dri.xml on May 6 2012 3:00:44am EDT. + This file was generated by xf86dri.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ +// Xf86driInit must be called before using the XFree86-DRI extension. +func (c *Conn) Xf86driInit() error { + reply, err := c.QueryExtension(11, "XFree86-DRI").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XFree86-DRI could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XFree86-DRI"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XFree86-DRI"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XFree86-DRI"] = make(map[int]newEventFun) +} + // Skipping definition for base type 'Int8' // Skipping definition for base type 'Card16' diff --git a/nexgb/auto_xf86vidmode.go b/nexgb/auto_xf86vidmode.go index aefadf7..649244d 100644 --- a/nexgb/auto_xf86vidmode.go +++ b/nexgb/auto_xf86vidmode.go @@ -1,11 +1,33 @@ package xgb /* - This file was generated by xf86vidmode.xml on May 6 2012 3:00:44am EDT. + This file was generated by xf86vidmode.xml on May 6 2012 5:48:47pm EDT. This file is automatically generated. Edit at your peril! */ -// Skipping definition for base type 'Card16' +// Xf86vidmodeInit must be called before using the XFree86-VidModeExtension extension. +func (c *Conn) Xf86vidmodeInit() error { + reply, err := c.QueryExtension(24, "XFree86-VidModeExtension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XFree86-VidModeExtension could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XFree86-VidModeExtension"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XFree86-VidModeExtension"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XFree86-VidModeExtension"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Char' @@ -31,6 +53,8 @@ package xgb // Skipping definition for base type 'Int8' +// Skipping definition for base type 'Card16' + const ( Xf86vidmodeModeFlagPositiveHsync = 1 Xf86vidmodeModeFlagNegativeHsync = 2 diff --git a/nexgb/auto_xfixes.go b/nexgb/auto_xfixes.go index 9f1d105..aae1afb 100644 --- a/nexgb/auto_xfixes.go +++ b/nexgb/auto_xfixes.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xfixes.xml on May 6 2012 3:00:44am EDT. + This file was generated by xfixes.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -11,6 +11,30 @@ package xgb // import "render" // import "shape" +// XfixesInit must be called before using the XFIXES extension. +func (c *Conn) XfixesInit() error { + reply, err := c.QueryExtension(6, "XFIXES").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XFIXES could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XFIXES"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XFIXES"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XFIXES"] = make(map[int]newEventFun) +} + // Skipping definition for base type 'Card8' // Skipping definition for base type 'Int16' @@ -178,7 +202,7 @@ func (v XfixesSelectionNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewXfixesSelectionNotifyEvent + newExtEventFuncs["XFIXES"][0] = NewXfixesSelectionNotifyEvent } // Event definition XfixesCursorNotify (1) @@ -273,7 +297,7 @@ func (v XfixesCursorNotifyEvent) String() string { } func init() { - newEventFuncs[1] = NewXfixesCursorNotifyEvent + newExtEventFuncs["XFIXES"][1] = NewXfixesCursorNotifyEvent } // Error definition XfixesBadRegion (0) diff --git a/nexgb/auto_xinerama.go b/nexgb/auto_xinerama.go index 6c08447..d751710 100644 --- a/nexgb/auto_xinerama.go +++ b/nexgb/auto_xinerama.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xinerama.xml on May 6 2012 3:00:45am EDT. + This file was generated by xinerama.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,42 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// XineramaInit must be called before using the XINERAMA extension. +func (c *Conn) XineramaInit() error { + reply, err := c.QueryExtension(8, "XINERAMA").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XINERAMA could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XINERAMA"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XINERAMA"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XINERAMA"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Card32' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Bool' + // Skipping definition for base type 'Float' // Skipping definition for base type 'Id' @@ -23,18 +59,6 @@ package xgb // Skipping definition for base type 'Byte' -// Skipping definition for base type 'Int8' - -// Skipping definition for base type 'Card16' - -// Skipping definition for base type 'Char' - -// Skipping definition for base type 'Card32' - -// Skipping definition for base type 'Double' - -// Skipping definition for base type 'Bool' - // 'XineramaScreenInfo' struct definition // Size: 8 type XineramaScreenInfo struct { diff --git a/nexgb/auto_xinput.go b/nexgb/auto_xinput.go index d300bca..ae122b8 100644 --- a/nexgb/auto_xinput.go +++ b/nexgb/auto_xinput.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xinput.xml on May 6 2012 3:00:45am EDT. + This file was generated by xinput.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,42 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// XinputInit must be called before using the XInputExtension extension. +func (c *Conn) XinputInit() error { + reply, err := c.QueryExtension(15, "XInputExtension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XInputExtension could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XInputExtension"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XInputExtension"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XInputExtension"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Int8' + +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Card32' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Bool' + // Skipping definition for base type 'Float' // Skipping definition for base type 'Id' @@ -23,18 +59,6 @@ package xgb // Skipping definition for base type 'Byte' -// Skipping definition for base type 'Int8' - -// Skipping definition for base type 'Card16' - -// Skipping definition for base type 'Char' - -// Skipping definition for base type 'Card32' - -// Skipping definition for base type 'Double' - -// Skipping definition for base type 'Bool' - const ( XinputValuatorModeRelative = 0 XinputValuatorModeAbsolute = 1 @@ -3307,7 +3331,7 @@ func (v XinputDeviceValuatorEvent) String() string { } func init() { - newEventFuncs[0] = NewXinputDeviceValuatorEvent + newExtEventFuncs["XInputExtension"][0] = NewXinputDeviceValuatorEvent } // Event definition XinputDeviceKeyPress (1) @@ -3461,7 +3485,7 @@ func (v XinputDeviceKeyPressEvent) String() string { } func init() { - newEventFuncs[1] = NewXinputDeviceKeyPressEvent + newExtEventFuncs["XInputExtension"][1] = NewXinputDeviceKeyPressEvent } // Event definition XinputFocusIn (6) @@ -3556,7 +3580,7 @@ func (v XinputFocusInEvent) String() string { } func init() { - newEventFuncs[6] = NewXinputFocusInEvent + newExtEventFuncs["XInputExtension"][6] = NewXinputFocusInEvent } // Event definition XinputDeviceStateNotify (10) @@ -3684,7 +3708,7 @@ func (v XinputDeviceStateNotifyEvent) String() string { } func init() { - newEventFuncs[10] = NewXinputDeviceStateNotifyEvent + newExtEventFuncs["XInputExtension"][10] = NewXinputDeviceStateNotifyEvent } // Event definition XinputDeviceMappingNotify (11) @@ -3784,7 +3808,7 @@ func (v XinputDeviceMappingNotifyEvent) String() string { } func init() { - newEventFuncs[11] = NewXinputDeviceMappingNotifyEvent + newExtEventFuncs["XInputExtension"][11] = NewXinputDeviceMappingNotifyEvent } // Event definition XinputChangeDeviceNotify (12) @@ -3863,7 +3887,7 @@ func (v XinputChangeDeviceNotifyEvent) String() string { } func init() { - newEventFuncs[12] = NewXinputChangeDeviceNotifyEvent + newExtEventFuncs["XInputExtension"][12] = NewXinputChangeDeviceNotifyEvent } // Event definition XinputDeviceKeyStateNotify (13) @@ -3929,7 +3953,7 @@ func (v XinputDeviceKeyStateNotifyEvent) String() string { } func init() { - newEventFuncs[13] = NewXinputDeviceKeyStateNotifyEvent + newExtEventFuncs["XInputExtension"][13] = NewXinputDeviceKeyStateNotifyEvent } // Event definition XinputDeviceButtonStateNotify (14) @@ -3995,7 +4019,7 @@ func (v XinputDeviceButtonStateNotifyEvent) String() string { } func init() { - newEventFuncs[14] = NewXinputDeviceButtonStateNotifyEvent + newExtEventFuncs["XInputExtension"][14] = NewXinputDeviceButtonStateNotifyEvent } // Event definition XinputDevicePresenceNotify (15) @@ -4087,7 +4111,7 @@ func (v XinputDevicePresenceNotifyEvent) String() string { } func init() { - newEventFuncs[15] = NewXinputDevicePresenceNotifyEvent + newExtEventFuncs["XInputExtension"][15] = NewXinputDevicePresenceNotifyEvent } // EventCopy definition XinputDeviceKeyRelease (2) @@ -4129,7 +4153,7 @@ func (v XinputDeviceKeyReleaseEvent) String() string { } func init() { - newEventFuncs[2] = NewXinputDeviceKeyReleaseEvent + newExtEventFuncs["XInputExtension"][2] = NewXinputDeviceKeyReleaseEvent } // EventCopy definition XinputDeviceButtonPress (3) @@ -4171,7 +4195,7 @@ func (v XinputDeviceButtonPressEvent) String() string { } func init() { - newEventFuncs[3] = NewXinputDeviceButtonPressEvent + newExtEventFuncs["XInputExtension"][3] = NewXinputDeviceButtonPressEvent } // EventCopy definition XinputDeviceButtonRelease (4) @@ -4213,7 +4237,7 @@ func (v XinputDeviceButtonReleaseEvent) String() string { } func init() { - newEventFuncs[4] = NewXinputDeviceButtonReleaseEvent + newExtEventFuncs["XInputExtension"][4] = NewXinputDeviceButtonReleaseEvent } // EventCopy definition XinputDeviceMotionNotify (5) @@ -4255,7 +4279,7 @@ func (v XinputDeviceMotionNotifyEvent) String() string { } func init() { - newEventFuncs[5] = NewXinputDeviceMotionNotifyEvent + newExtEventFuncs["XInputExtension"][5] = NewXinputDeviceMotionNotifyEvent } // EventCopy definition XinputProximityIn (8) @@ -4297,7 +4321,7 @@ func (v XinputProximityInEvent) String() string { } func init() { - newEventFuncs[8] = NewXinputProximityInEvent + newExtEventFuncs["XInputExtension"][8] = NewXinputProximityInEvent } // EventCopy definition XinputProximityOut (9) @@ -4339,7 +4363,7 @@ func (v XinputProximityOutEvent) String() string { } func init() { - newEventFuncs[9] = NewXinputProximityOutEvent + newExtEventFuncs["XInputExtension"][9] = NewXinputProximityOutEvent } // EventCopy definition XinputFocusOut (7) @@ -4374,7 +4398,7 @@ func (v XinputFocusOutEvent) String() string { } func init() { - newEventFuncs[7] = NewXinputFocusOutEvent + newExtEventFuncs["XInputExtension"][7] = NewXinputFocusOutEvent } // Error definition XinputDevice (0) diff --git a/nexgb/auto_xprint.go b/nexgb/auto_xprint.go index 6790a86..6c9be85 100644 --- a/nexgb/auto_xprint.go +++ b/nexgb/auto_xprint.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xprint.xml on May 6 2012 3:00:45am EDT. + This file was generated by xprint.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,15 +9,29 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" -// Skipping definition for base type 'Card16' +// XprintInit must be called before using the XpExtension extension. +func (c *Conn) XprintInit() error { + reply, err := c.QueryExtension(11, "XpExtension").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XpExtension could be found on on the server.") + } -// Skipping definition for base type 'Char' + c.extLock.Lock() + c.extensions["XpExtension"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XpExtension"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Card32' + return nil +} -// Skipping definition for base type 'Double' - -// Skipping definition for base type 'Bool' +func init() { + newExtEventFuncs["XpExtension"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Float' @@ -35,6 +49,16 @@ package xgb // Skipping definition for base type 'Int8' +// Skipping definition for base type 'Card16' + +// Skipping definition for base type 'Char' + +// Skipping definition for base type 'Card32' + +// Skipping definition for base type 'Double' + +// Skipping definition for base type 'Bool' + const ( XprintGetDocFinished = 0 XprintGetDocSecondConsumer = 1 @@ -241,7 +265,7 @@ func (v XprintNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewXprintNotifyEvent + newExtEventFuncs["XpExtension"][0] = NewXprintNotifyEvent } // Event definition XprintAttributNotify (1) @@ -307,7 +331,7 @@ func (v XprintAttributNotifyEvent) String() string { } func init() { - newEventFuncs[1] = NewXprintAttributNotifyEvent + newExtEventFuncs["XpExtension"][1] = NewXprintAttributNotifyEvent } // Error definition XprintBadContext (0) diff --git a/nexgb/auto_xproto.go b/nexgb/auto_xproto.go index edee988..84b193d 100644 --- a/nexgb/auto_xproto.go +++ b/nexgb/auto_xproto.go @@ -1,14 +1,10 @@ package xgb /* - This file was generated by xproto.xml on May 6 2012 3:00:45am EDT. + This file was generated by xproto.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ -// Skipping definition for base type 'Int16' - -// Skipping definition for base type 'Int32' - // Skipping definition for base type 'Void' // Skipping definition for base type 'Byte' @@ -31,6 +27,10 @@ package xgb // Skipping definition for base type 'Card8' +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + const ( VisualClassStaticGray = 0 VisualClassGrayScale = 1 diff --git a/nexgb/auto_xselinux.go b/nexgb/auto_xselinux.go index 57908c2..e3dfbf3 100644 --- a/nexgb/auto_xselinux.go +++ b/nexgb/auto_xselinux.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xselinux.xml on May 6 2012 3:00:45am EDT. + This file was generated by xselinux.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,42 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// XselinuxInit must be called before using the SELinux extension. +func (c *Conn) XselinuxInit() error { + reply, err := c.QueryExtension(7, "SELinux").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named SELinux could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["SELinux"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["SELinux"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["SELinux"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Id' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + // Skipping definition for base type 'Void' // Skipping definition for base type 'Byte' @@ -23,18 +59,6 @@ package xgb // Skipping definition for base type 'Double' -// Skipping definition for base type 'Bool' - -// Skipping definition for base type 'Float' - -// Skipping definition for base type 'Id' - -// Skipping definition for base type 'Card8' - -// Skipping definition for base type 'Int16' - -// Skipping definition for base type 'Int32' - // 'XselinuxListItem' struct definition // Size: ((12 + pad((int(ObjectContextLen) * 1))) + pad((int(DataContextLen) * 1))) type XselinuxListItem struct { diff --git a/nexgb/auto_xtest.go b/nexgb/auto_xtest.go index 3c4ce7c..565c3d1 100644 --- a/nexgb/auto_xtest.go +++ b/nexgb/auto_xtest.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xtest.xml on May 6 2012 3:00:45am EDT. + This file was generated by xtest.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,40 @@ package xgb // in one package. They are still listed here for reference. // import "xproto" +// XtestInit must be called before using the XTEST extension. +func (c *Conn) XtestInit() error { + reply, err := c.QueryExtension(5, "XTEST").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XTEST could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XTEST"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XTEST"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XTEST"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Bool' + +// Skipping definition for base type 'Float' + +// Skipping definition for base type 'Id' + +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Int16' + // Skipping definition for base type 'Int32' // Skipping definition for base type 'Void' @@ -25,16 +59,6 @@ package xgb // Skipping definition for base type 'Double' -// Skipping definition for base type 'Bool' - -// Skipping definition for base type 'Float' - -// Skipping definition for base type 'Id' - -// Skipping definition for base type 'Card8' - -// Skipping definition for base type 'Int16' - const ( XtestCursorNone = 0 XtestCursorCurrent = 1 diff --git a/nexgb/auto_xv.go b/nexgb/auto_xv.go index 9e560a0..0ce0c64 100644 --- a/nexgb/auto_xv.go +++ b/nexgb/auto_xv.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xv.xml on May 6 2012 3:00:45am EDT. + This file was generated by xv.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -10,11 +10,29 @@ package xgb // import "xproto" // import "shm" -// Skipping definition for base type 'Card8' +// XvInit must be called before using the XVideo extension. +func (c *Conn) XvInit() error { + reply, err := c.QueryExtension(6, "XVideo").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XVideo could be found on on the server.") + } -// Skipping definition for base type 'Int16' + c.extLock.Lock() + c.extensions["XVideo"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XVideo"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() -// Skipping definition for base type 'Int32' + return nil +} + +func init() { + newExtEventFuncs["XVideo"] = make(map[int]newEventFun) +} // Skipping definition for base type 'Void' @@ -36,6 +54,12 @@ package xgb // Skipping definition for base type 'Id' +// Skipping definition for base type 'Card8' + +// Skipping definition for base type 'Int16' + +// Skipping definition for base type 'Int32' + const ( XvTypeInputMask = 1 XvTypeOutputMask = 2 @@ -938,7 +962,7 @@ func (v XvVideoNotifyEvent) String() string { } func init() { - newEventFuncs[0] = NewXvVideoNotifyEvent + newExtEventFuncs["XVideo"][0] = NewXvVideoNotifyEvent } // Event definition XvPortNotify (1) @@ -1025,7 +1049,7 @@ func (v XvPortNotifyEvent) String() string { } func init() { - newEventFuncs[1] = NewXvPortNotifyEvent + newExtEventFuncs["XVideo"][1] = NewXvPortNotifyEvent } // Error definition XvBadPort (0) diff --git a/nexgb/auto_xvmc.go b/nexgb/auto_xvmc.go index 1d8814d..61eab40 100644 --- a/nexgb/auto_xvmc.go +++ b/nexgb/auto_xvmc.go @@ -1,7 +1,7 @@ package xgb /* - This file was generated by xvmc.xml on May 6 2012 3:00:45am EDT. + This file was generated by xvmc.xml on May 6 2012 5:48:48pm EDT. This file is automatically generated. Edit at your peril! */ @@ -9,6 +9,36 @@ package xgb // in one package. They are still listed here for reference. // import "xv" +// XvmcInit must be called before using the XVideo-MotionCompensation extension. +func (c *Conn) XvmcInit() error { + reply, err := c.QueryExtension(25, "XVideo-MotionCompensation").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return newError("No extension named XVideo-MotionCompensation could be found on on the server.") + } + + c.extLock.Lock() + c.extensions["XVideo-MotionCompensation"] = reply.MajorOpcode + for evNum, fun := range newExtEventFuncs["XVideo-MotionCompensation"] { + newEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + c.extLock.Unlock() + + return nil +} + +func init() { + newExtEventFuncs["XVideo-MotionCompensation"] = make(map[int]newEventFun) +} + +// Skipping definition for base type 'Void' + +// Skipping definition for base type 'Byte' + +// Skipping definition for base type 'Int8' + // Skipping definition for base type 'Card16' // Skipping definition for base type 'Char' @@ -29,12 +59,6 @@ package xgb // Skipping definition for base type 'Int32' -// Skipping definition for base type 'Void' - -// Skipping definition for base type 'Byte' - -// Skipping definition for base type 'Int8' - // Skipping resource definition of 'Context' // Skipping resource definition of 'Surface' diff --git a/nexgb/cookie.go b/nexgb/cookie.go index 7f54a22..8c0774d 100644 --- a/nexgb/cookie.go +++ b/nexgb/cookie.go @@ -9,11 +9,11 @@ import ( // '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 + conn *Conn + Sequence uint16 replyChan chan []byte errorChan chan error - pingChan chan bool + pingChan chan bool } // newCookie creates a new cookie with the correct channels initialized @@ -24,11 +24,11 @@ type cookie struct { // corresponding to this cookie is sent over the wire. func (c *Conn) newCookie(checked, reply bool) *cookie { cookie := &cookie{ - conn: c, - Sequence: 0, // we add the sequence id just before sending a request + conn: c, + Sequence: 0, // we add the sequence id just before sending a request replyChan: nil, errorChan: nil, - pingChan: nil, + pingChan: nil, } // There are four different kinds of cookies: @@ -151,4 +151,3 @@ func (c cookie) check() error { } panic("unreachable") } - diff --git a/nexgb/xgb.go b/nexgb/xgb.go index 26c0138..223b6e2 100644 --- a/nexgb/xgb.go +++ b/nexgb/xgb.go @@ -12,7 +12,6 @@ import ( "io" "net" "os" - "strings" "sync" ) @@ -22,27 +21,24 @@ const ( // 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 - readBuffer = 100 - writeBuffer = 100 ) // A Conn represents a connection to an X server. type Conn struct { host string conn net.Conn - err error display string defaultScreen int Setup SetupInfo - extensions map[string]byte - eventChan chan eventOrError + eventChan chan eventOrError cookieChan chan *cookie - xidChan chan xid - seqChan chan uint16 - reqChan chan *request + xidChan chan xid + seqChan chan uint16 + reqChan chan *request - extLock sync.Mutex + extLock sync.Mutex + extensions map[string]byte } // NewConn creates a new connection instance. It initializes locks, data @@ -109,9 +105,16 @@ type Event interface { String() string } +type newEventFun func(buf []byte) Event + // newEventFuncs is a map from event numbers to functions that create // the corresponding event. -var newEventFuncs = map[int]func(buf []byte) Event{} +var newEventFuncs = make(map[int]newEventFun) + +// newExtEventFuncs is a temporary map that stores event constructor functions +// for each extension. When an extension is initialize, each event for that +// extension is added to the 'newEventFuncs' map. +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. @@ -144,7 +147,7 @@ func (c *Conn) NewId() (Id, error) { // 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 Id + id Id err error } @@ -174,7 +177,7 @@ func (conn *Conn) generateXIds() { last := uint32(0) for { // TODO: Use the XC Misc extension to look for released ids. - if last > 0 && last >= max - inc + 1 { + if last > 0 && last >= max-inc+1 { conn.xidChan <- xid{ id: Id(0), err: errors.New("There are no more available resource" + @@ -184,7 +187,7 @@ func (conn *Conn) generateXIds() { last += inc conn.xidChan <- xid{ - id: Id(last | conn.Setup.ResourceIdBase), + id: Id(last | conn.Setup.ResourceIdBase), err: nil, } } @@ -206,7 +209,7 @@ func (c *Conn) generateSeqIds() { seqid := uint16(1) for { c.seqChan <- seqid - if seqid == uint16((1 << 16) - 1) { + if seqid == uint16((1<<16)-1) { seqid = 0 } else { seqid++ @@ -218,7 +221,7 @@ func (c *Conn) generateSeqIds() { // 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 + buf []byte cookie *cookie } @@ -238,7 +241,7 @@ func (c *Conn) sendRequests() { // 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 len(c.cookieChan) == cookieBuffer-1 { cookie := c.newCookie(true, true) cookie.Sequence = c.newSequenceId() c.cookieChan <- cookie @@ -277,9 +280,9 @@ func (c *Conn) writeBuffer(buf []byte) bool { // Finally, cookies that came "before" this reply are always cleaned up. func (c *Conn) readResponses() { var ( - err Error - event Event - seq uint16 + err Error + event Event + seq uint16 replyBytes []byte ) @@ -300,9 +303,9 @@ func (c *Conn) readResponses() { newErrFun, ok := newErrorFuncs[int(buf[1])] if !ok { fmt.Fprintf(os.Stderr, - "BUG: " + - "Could not find error constructor function for error " + - "with number %d.", buf[1]) + "BUG: "+ + "Could not find error constructor function for error "+ + "with number %d.\n", buf[1]) continue } err = newErrFun(buf) @@ -316,7 +319,7 @@ func (c *Conn) readResponses() { // check to see if this reply has more bytes to be read size := Get32(buf[4:]) if size > 0 { - byteCount := 32 + size * 4 + byteCount := 32 + size*4 biggerBuf := make([]byte, byteCount) copy(biggerBuf[:32], buf) if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil { @@ -340,9 +343,9 @@ func (c *Conn) readResponses() { newEventFun, ok := newEventFuncs[evNum] if !ok { fmt.Fprintf(os.Stderr, - "BUG: " + - "Could not find event constructor function for event " + - "with number %d.", evNum) + "BUG: "+ + "Could not find event constructor function for event "+ + "with number %d.", evNum) continue } @@ -380,8 +383,8 @@ func (c *Conn) readResponses() { } else { // this is a reply if cookie.replyChan == nil { fmt.Fprintf(os.Stderr, - "Reply with sequence id %d does not have a " + - "cookie with a valid reply channel.\n", seq) + "Reply with sequence id %d does not have a "+ + "cookie with a valid reply channel.\n", seq) continue } else { cookie.replyChan <- replyBytes @@ -394,20 +397,20 @@ func (c *Conn) readResponses() { // Checked requests with replies case cookie.replyChan != nil && cookie.errorChan != nil: fmt.Fprintf(os.Stderr, - "Found cookie with sequence id %d that is expecting a " + - "reply but will never get it. Currently on sequence " + - "number %d\n", cookie.Sequence, seq) + "Found cookie with sequence id %d that is expecting a "+ + "reply but will never get it. Currently on sequence "+ + "number %d\n", cookie.Sequence, seq) // Unchecked requests with replies case cookie.replyChan != nil && cookie.pingChan != nil: fmt.Fprintf(os.Stderr, - "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\n", cookie.Sequence, seq) + "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\n", 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. + // Unchecked requests without replies don't have any channels, + // so we can't do anything with them except let them pass by. } } } @@ -446,24 +449,3 @@ func (c *Conn) PollForEvent() (Event, Error) { } panic("unreachable") } - -// RegisterExtension adds the respective extension's major op code to -// the extensions map. -func (c *Conn) RegisterExtension(name string) error { - nameUpper := strings.ToUpper(name) - reply, err := c.QueryExtension(uint16(len(nameUpper)), nameUpper).Reply() - - switch { - case err != nil: - return err - case !reply.Present: - return errors.New(fmt.Sprintf("No extension named '%s' is present.", - nameUpper)) - } - - c.extLock.Lock() - c.extensions[nameUpper] = reply.MajorOpcode - c.extLock.Unlock() - - return nil -} diff --git a/nexgb/xgb_help.go b/nexgb/xgb_help.go index b54ab41..6d07938 100644 --- a/nexgb/xgb_help.go +++ b/nexgb/xgb_help.go @@ -1,6 +1,7 @@ package xgb import ( + "errors" "fmt" "strings" ) @@ -16,6 +17,12 @@ func sprintf(format string, v ...interface{}) string { return fmt.Sprintf(format, v...) } +// newError is just a wrapper for errors.New. Exists for the same reason +// that 'stringsJoin' and 'sprintf' exists. +func newError(format string, v ...interface{}) error { + return errors.New(fmt.Sprintf(format, v...)) +} + // Pad a length to align on 4 bytes. func pad(n int) int { return (n + 3) & ^3 diff --git a/nexgb/xgb_test.go b/nexgb/xgb_test.go new file mode 100644 index 0000000..9665164 --- /dev/null +++ b/nexgb/xgb_test.go @@ -0,0 +1,358 @@ +package xgb + +/* + 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. +*/ + +import ( + "fmt" + "log" + "math/rand" + "testing" + "time" +) + +// The X connection used throughout testing. +var X *Conn + +// init initializes the X connection, seeds the RNG and starts waiting +// for events. +func init() { + var err error + + X, err = NewConn() + if err != nil { + log.Fatal(err) + } + + rand.Seed(time.Now().UnixNano()) + + go grabEvents() +} + +/******************************************************************************/ +// Tests +/******************************************************************************/ + +// TestSynchronousError purposefully causes a BadLength error in an +// InternAtom request, and checks it synchronously. +func TestSynchronousError(t *testing.T) { + err := X.MapWindowChecked(0).Check() // resource id 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) { + X.MapWindow(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++ { + X.NoOperation() + } + 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 := X.InternAtom(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 := X.NewId() + if err != nil { + t.Fatalf("NewId: %s", err) + } + + screen := X.DefaultScreen() // alias + err = X.CreateWindowChecked(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 = X.MapWindowChecked(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 = X.ChangeWindowAttributesChecked(wid, + CwEventMask, []uint32{EventMaskStructureNotify}).Check() + if err != nil { + t.Fatalf("ChangeWindowAttributes: %s", err) + } + + err = X.ConfigureWindowChecked(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 = X.ChangeWindowAttributesChecked(wid, + CwEventMask, []uint32{0}).Check() + if err != nil { + t.Fatalf("ChangeWindowAttributes: %s", err) + } + + err = X.DestroyWindowChecked(wid).Check() + if err != nil { + t.Fatalf("DestroyWindow: %s", err) + } +} + +/******************************************************************************/ +// 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 better 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] = X.InternAtom(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++ { + X.InternAtom(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) { + propAtom, err := X.InternAtom(false, uint16(len(prop)), prop).Reply() + if err != nil { + return "", fmt.Errorf("InternAtom: %s", err) + } + + typName := "UTF8_STRING" + typAtom, err := X.InternAtom(false, uint16(len(typName)), typName).Reply() + if err != nil { + return "", fmt.Errorf("InternAtom: %s", err) + } + + err = X.ChangePropertyChecked(PropModeReplace, X.DefaultScreen().Root, + propAtom.Atom, typAtom.Atom, 8, uint32(len(val)), []byte(val)).Check() + if err != nil { + return "", fmt.Errorf("ChangeProperty: %s", err) + } + + reply, err := X.GetProperty(false, X.DefaultScreen().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 Event + err 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 +}