add more extension cruft. make extension checking more uniform.

This commit is contained in:
Andrew Gallant (Ocelot) 2012-05-06 17:48:40 -04:00
parent 135cee5761
commit 6d545e723a
7 changed files with 59 additions and 11 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"log" "log"
"strings"
"time" "time"
) )
@ -70,6 +71,43 @@ func (c *Context) Morph(xmlBytes []byte) {
c.Putln("") c.Putln("")
} }
// If this is an extension, create a function to initialize the extension
// before it can be used.
if c.protocol.isExt() {
name := strings.Title(c.protocol.Name) + "Init"
xname := c.protocol.ExtXName
c.Putln("// %s must be called before using the %s extension.",
name, xname)
c.Putln("func (c *Conn) %s() error {", name)
c.Putln("reply, err := c.QueryExtension(%d, \"%s\").Reply()",
len(xname), xname)
c.Putln("switch {")
c.Putln("case err != nil:")
c.Putln("return err")
c.Putln("case !reply.Present:")
c.Putln("return newError(\"No extension named %s could be found on " +
"on the server.\")", xname)
c.Putln("}")
c.Putln("")
c.Putln("c.extLock.Lock()")
c.Putln("c.extensions[\"%s\"] = reply.MajorOpcode", xname)
c.Putln("for evNum, fun := range newExtEventFuncs[\"%s\"] {", xname)
c.Putln("newEventFuncs[int(reply.FirstEvent) + evNum] = fun")
c.Putln("}")
c.Putln("c.extLock.Unlock()")
c.Putln("")
c.Putln("return nil")
c.Putln("}")
c.Putln("")
// Make sure newExtEventFuncs["EXT_NAME"] map is initialized.
c.Putln("func init() {")
c.Putln("newExtEventFuncs[\"%s\"] = make(map[int]newEventFun)", xname)
c.Putln("}")
c.Putln("")
}
// Now write Go source code // Now write Go source code
for _, typ := range c.protocol.Types { for _, typ := range c.protocol.Types {
typ.Define(c) typ.Define(c)

View File

@ -64,7 +64,7 @@ func (e *Error) ImplementsError(c *Context) {
c.Putln("}") c.Putln("}")
c.Putln("") c.Putln("")
c.Putln("func (err %s) BadId() Id {", e.ErrType()) c.Putln("func (err %s) BadId() Id {", e.ErrType())
if c.protocol.Name == "xproto" { if !c.protocol.isExt() {
c.Putln("return Id(err.BadValue)") c.Putln("return Id(err.BadValue)")
} else { } else {
c.Putln("return 0") c.Putln("return 0")

View File

@ -47,7 +47,12 @@ func (e *Event) Define(c *Context) {
// Let's the XGB event loop read this event. // Let's the XGB event loop read this event.
c.Putln("func init() {") c.Putln("func init() {")
if c.protocol.isExt() {
c.Putln("newExtEventFuncs[\"%s\"][%d] = New%s",
c.protocol.ExtXName, e.Number, e.EvType())
} else {
c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType()) c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType())
}
c.Putln("}") c.Putln("}")
c.Putln("") c.Putln("")
} }
@ -130,7 +135,12 @@ func (e *EventCopy) Define(c *Context) {
// Let's the XGB event loop read this event. // Let's the XGB event loop read this event.
c.Putln("func init() {") c.Putln("func init() {")
if c.protocol.isExt() {
c.Putln("newExtEventFuncs[\"%s\"][%d] = New%s",
c.protocol.ExtXName, e.Number, e.EvType())
} else {
c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType()) c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType())
}
c.Putln("}") c.Putln("}")
c.Putln("") c.Putln("")
} }

View File

@ -118,7 +118,7 @@ func (r *Request) WriteRequest(c *Context) {
c.Putln("b := 0") c.Putln("b := 0")
c.Putln("buf := make([]byte, size)") c.Putln("buf := make([]byte, size)")
c.Putln("") c.Putln("")
if strings.ToLower(c.protocol.Name) != "xproto" { if c.protocol.isExt() {
c.Putln("buf[b] = c.extensions[\"%s\"]", c.Putln("buf[b] = c.extensions[\"%s\"]",
strings.ToUpper(c.protocol.ExtXName)) strings.ToUpper(c.protocol.ExtXName))
c.Putln("b += 1") c.Putln("b += 1")
@ -128,17 +128,17 @@ func (r *Request) WriteRequest(c *Context) {
c.Putln("b += 1") c.Putln("b += 1")
c.Putln("") c.Putln("")
if len(r.Fields) == 0 { if len(r.Fields) == 0 {
if strings.ToLower(c.protocol.Name) == "xproto" { if !c.protocol.isExt() {
c.Putln("b += 1 // padding") c.Putln("b += 1 // padding")
} }
writeSize() writeSize()
} else if strings.ToLower(c.protocol.Name) != "xproto" { } else if c.protocol.isExt() {
writeSize() writeSize()
} }
for i, field := range r.Fields { for i, field := range r.Fields {
field.Write(c, "") field.Write(c, "")
c.Putln("") c.Putln("")
if i == 0 && strings.ToLower(c.protocol.Name) == "xproto" { if i == 0 && !c.protocol.isExt() {
writeSize() writeSize()
} }
} }

View File

@ -36,6 +36,6 @@ func (p *Protocol) Initialize() {
// isExt returns true if this protocol is an extension. // isExt returns true if this protocol is an extension.
// i.e., it's name isn't "xproto". // i.e., it's name isn't "xproto".
func (p *Protocol) isExt() bool { func (p *Protocol) isExt() bool {
return strings.ToLower(p.Name) == "xproto" return strings.ToLower(p.Name) != "xproto"
} }

View File

@ -22,7 +22,7 @@ type Request struct {
// It also initializes the reply if one exists, and all fields in this request. // It also initializes the reply if one exists, and all fields in this request.
func (r *Request) Initialize(p *Protocol) { func (r *Request) Initialize(p *Protocol) {
r.srcName = SrcName(p, r.xmlName) r.srcName = SrcName(p, r.xmlName)
if p.Name != "xproto" { if p.isExt() {
r.srcName = strings.Title(strings.ToLower(p.Name)) + r.srcName r.srcName = strings.Title(strings.ToLower(p.Name)) + r.srcName
} }
@ -93,7 +93,7 @@ func (r *Request) Size(c *Context) Size {
// request. In an extension request, this byte is always occupied // request. In an extension request, this byte is always occupied
// by the opcode of the request (while the first byte is always occupied // by the opcode of the request (while the first byte is always occupied
// by the opcode of the extension). // by the opcode of the extension).
if c.protocol.Name == "xproto" { if !c.protocol.isExt() {
size = size.Add(newFixedSize(3)) size = size.Add(newFixedSize(3))
} else { } else {
size = size.Add(newFixedSize(4)) size = size.Add(newFixedSize(4))

View File

@ -410,7 +410,7 @@ func TypeSrcName(p *Protocol, typ Type) string {
// Since there is no namespace, we need to look for a namespace // Since there is no namespace, we need to look for a namespace
// in the current context. // in the current context.
niceType := splitAndTitle(t) niceType := splitAndTitle(t)
if p.Name != "xproto" { if p.isExt() {
for _, typ2 := range p.Types { for _, typ2 := range p.Types {
if t == typ2.XmlName() { if t == typ2.XmlName() {
return strings.Title(p.Name) + niceType return strings.Title(p.Name) + niceType