aboutsummaryrefslogtreecommitdiff
path: root/nexgb
diff options
context:
space:
mode:
authorAndrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu>2012-05-07 01:00:45 -0400
committerAndrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu>2012-05-07 01:00:45 -0400
commitfd30f1512a713ae5b3cbacddfe9f29dfccc82047 (patch)
tree5801b9fe74106d9780efa23cd1b2c238ba5ffad9 /nexgb
parent6d545e723a7e972998a0e77adcf2219a31a9b800 (diff)
downloadhaven-fd30f1512a713ae5b3cbacddfe9f29dfccc82047.tar.gz
haven-fd30f1512a713ae5b3cbacddfe9f29dfccc82047.tar.xz
haven-fd30f1512a713ae5b3cbacddfe9f29dfccc82047.zip
added tests
Diffstat (limited to 'nexgb')
-rw-r--r--nexgb/Makefile6
-rw-r--r--nexgb/auto_bigreq.go26
-rw-r--r--nexgb/auto_composite.go38
-rw-r--r--nexgb/auto_damage.go36
-rw-r--r--nexgb/auto_dpms.go30
-rw-r--r--nexgb/auto_dri2.go30
-rw-r--r--nexgb/auto_ge.go34
-rw-r--r--nexgb/auto_glx.go40
-rw-r--r--nexgb/auto_randr.go38
-rw-r--r--nexgb/auto_record.go38
-rw-r--r--nexgb/auto_render.go38
-rw-r--r--nexgb/auto_res.go42
-rw-r--r--nexgb/auto_screensaver.go48
-rw-r--r--nexgb/auto_shape.go28
-rw-r--r--nexgb/auto_shm.go36
-rw-r--r--nexgb/auto_sync.go30
-rw-r--r--nexgb/auto_xc_misc.go42
-rw-r--r--nexgb/auto_xevie.go30
-rw-r--r--nexgb/auto_xf86dri.go26
-rw-r--r--nexgb/auto_xf86vidmode.go28
-rw-r--r--nexgb/auto_xfixes.go30
-rw-r--r--nexgb/auto_xinerama.go46
-rw-r--r--nexgb/auto_xinput.go78
-rw-r--r--nexgb/auto_xprint.go42
-rw-r--r--nexgb/auto_xproto.go10
-rw-r--r--nexgb/auto_xselinux.go46
-rw-r--r--nexgb/auto_xtest.go46
-rw-r--r--nexgb/auto_xv.go36
-rw-r--r--nexgb/auto_xvmc.go38
-rw-r--r--nexgb/cookie.go13
-rw-r--r--nexgb/xgb.go98
-rw-r--r--nexgb/xgb_help.go7
-rw-r--r--nexgb/xgb_test.go358
33 files changed, 1256 insertions, 256 deletions
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'
-
-// Skipping definition for base type 'Id'
+// 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 'Card8'
+ 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 'Int16'
+ return nil
+}
-// 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'
-
-// Skipping definition for base type 'Char'
+// 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 'Card32'
+ 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 'Double'
+ return nil
+}
-// 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'
-
-// Skipping definition for base type 'Char'
-
-// Skipping definition for base type 'Card32'
+// 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 'Double'
+ 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 'Bool'
+ return nil
+}
-// 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,19 +9,29 @@ package xgb
// in one package. They are still listed here for reference.
// import "xproto"
-// Skipping definition for base type 'Char'
-
-// Skipping definition for base type 'Card32'
-
-// Skipping definition for base type 'Double'
-
-// Skipping definition for base type 'Bool'
+// 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.")
+ }
-// Skipping definition for base type 'Float'
+ 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()
-// Skipping definition for base type 'Id'
+ return nil
+}
-// Skipping definition for base type 'Card8'
+func init() {
+ newExtEventFuncs["MIT-SCREEN-SAVER"] = make(map[int]newEventFun)
+}
// Skipping definition for base type 'Int16'
@@ -35,6 +45,20 @@ package xgb
// 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'
+
+// Skipping definition for base type 'Card8'
+
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'
-
-// Skipping definition for base type 'Id'
-
-// Skipping definition for base type 'Card8'
+// 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 'Int16'
+ 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 'Int32'
+ return nil
+}
-// 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,19 +9,29 @@ package xgb
// in one package. They are still listed here for reference.
// import "xproto"
-// Skipping definition for base type 'Float'
-
-// Skipping definition for base type 'Id'
-
-// Skipping definition for base type 'Card8'
-
-// Skipping definition for base type 'Int16'
+// 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.")
+ }
-// Skipping definition for base type 'Int32'
+ c.extLock.Lock()
+ c.extensions["XINERAMA"] = reply.MajorOpcode
+ for evNum, fun := range newExtEventFuncs["XINERAMA"] {
+ newEventFuncs[int(reply.FirstEvent)+evNum] = fun
+ }
+ c.extLock.Unlock()
-// Skipping definition for base type 'Void'
+ return nil
+}
-// Skipping definition for base type 'Byte'
+func init() {
+ newExtEventFuncs["XINERAMA"] = make(map[int]newEventFun)
+}
// Skipping definition for base type 'Int8'
@@ -35,6 +45,20 @@ 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'
+
+// Skipping definition for base type 'Byte'
+
// '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,19 +9,29 @@ package xgb
// in one package. They are still listed here for reference.
// import "xproto"
-// Skipping definition for base type 'Float'
-
-// Skipping definition for base type 'Id'
-
-// Skipping definition for base type 'Card8'
-
-// Skipping definition for base type 'Int16'
+// 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.")
+ }
-// Skipping definition for base type 'Int32'
+ c.extLock.Lock()
+ c.extensions["XInputExtension"] = reply.MajorOpcode
+ for evNum, fun := range newExtEventFuncs["XInputExtension"] {
+ newEventFuncs[int(reply.FirstEvent)+evNum] = fun
+ }
+ c.extLock.Unlock()
-// Skipping definition for base type 'Void'
+ return nil
+}
-// Skipping definition for base type 'Byte'
+func init() {
+ newExtEventFuncs["XInputExtension"] = make(map[int]newEventFun)
+}
// Skipping definition for base type 'Int8'
@@ -35,6 +45,20 @@ 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'
+
+// Skipping definition for base type 'Byte'
+
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'
-
-// Skipping definition for base type 'Char'
+// 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 'Card32'
+ 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 'Double'
+ return nil
+}
-// 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,19 +9,29 @@ package xgb
// in one package. They are still listed here for reference.
// import "xproto"
-// Skipping definition for base type 'Void'
-
-// Skipping definition for base type 'Byte'
-
-// Skipping definition for base type 'Int8'
-
-// Skipping definition for base type 'Card16'
+// 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.")
+ }
-// Skipping definition for base type 'Char'
+ c.extLock.Lock()
+ c.extensions["SELinux"] = reply.MajorOpcode
+ for evNum, fun := range newExtEventFuncs["SELinux"] {
+ 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["SELinux"] = make(map[int]newEventFun)
+}
// Skipping definition for base type 'Bool'
@@ -35,6 +45,20 @@ 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 definition for base type 'Card16'
+
+// Skipping definition for base type 'Char'
+
+// Skipping definition for base type 'Card32'
+
+// Skipping definition for base type 'Double'
+
// '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
+}