BurntSushi / xgb

The X Go Binding is a low-level API to communicate with the X server. It is modeled on XCB and supports many X extensions.
Other
487 stars 74 forks source link

record extension will cause xgb blocked #16

Open snyh opened 10 years ago

snyh commented 10 years ago

test code:

package main

import "fmt"
import "github.com/BurntSushi/xgb/record"
import "github.com/BurntSushi/xgb"
import "github.com/BurntSushi/xgb/xproto"

func main() {
    c, err := xgb.NewConn()
    if err != nil {
        fmt.Println("NewCOnnerr:", err)
    }

    record.Init(c)

    record.QueryVersion(c, 1, 13)

    rc, err := record.NewContextId(c)
    if err != nil {
        panic(err)
    }

    ranges := []record.Range{record.Range{}}
    ranges[0].DeviceEvents.First = xproto.KeyPress
    ranges[0].DeviceEvents.Last = xproto.ButtonRelease
    fmt.Println(ranges[0].Bytes())

    clientspec := []record.ClientSpec{record.ClientSpec(record.CsAllClients)}

    record.CreateContextChecked(c, rc, record.ElementHeader(1), 1, 1, clientspec, ranges).Reply()

    rr, err := record.EnableContext(c, rc).Reply()
    fmt.Println(rr, err)

    record.EnableContext(c, rc).Reply()
}

below is the x11 request and reply captured by wireshark.

https://drive.google.com/file/d/0B9yQfM5tUO9uMXBqUEFUNkNfTk0/edit?usp=sharing

deepinscreenshot20131229001429

BurntSushi commented 10 years ago

Thanks for this. The next step, I think, is to produce an equivalent program with XCB and see what happens there.

I basically don't have the time to fix this right now. If you discover a fix, a pull request is welcome. Just make sure that any fixes you make are either in the core xgb package or in xgb/xgbgen. The rest of the code in this repo is automatically generated.

electricface commented 7 years ago

http://stackoverflow.com/questions/20823894/xcb-record-x11-extension-example xcb record example can your resolve this problem?

electricface commented 7 years ago

I write an example in golang

package main

import (
    "github.com/BurntSushi/xgb"
    "github.com/BurntSushi/xgb/record"
    "github.com/BurntSushi/xgb/xproto"
    "log"
)

var stop bool

func main() {
    x, err := xgb.NewConn()
    if err != nil {
        log.Fatal(err)
    }

    xData, err := xgb.NewConn()
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("x data conn: %p\n", xData)

    // xrecord
    if err := record.Init(x); err != nil {
        log.Fatal(err)
    }
    if err := record.Init(xData); err != nil {
        log.Fatal(err)
    }

    // xrecord version
    queryVersionReply, err := record.QueryVersion(x, 0, 0).Reply()
    if err != nil {
        log.Fatal(err)
    }
    log.Println(queryVersionReply.MajorVersion, queryVersionReply.MinorVersion)

    ctx, err := record.NewContextId(x)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("context id:", ctx)

    // create context
    ranges := []record.Range{record.Range{}}
    ranges[0].DeviceEvents.First = xproto.KeyPress
    ranges[0].DeviceEvents.Last = xproto.ButtonRelease
    log.Println(ranges[0].Bytes())
    clientspec := []record.ClientSpec{record.ClientSpec(record.CsAllClients)}

    err = record.CreateContextChecked(x, ctx, record.ElementHeader(0), 1, 1, clientspec, ranges).Check()
    if err != nil {
        log.Fatal(err)
    }

    // enable context
    cookie := record.EnableContext(xData, ctx)

    for !stop {
        log.Println("in loop")
        reply, err := cookie.Reply()
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("reply: %#v\n", reply)
        if reply.ClientSwapped {
            log.Fatal("reply.ClientSwapped is true")
        }
    }

}

I think the reason for the bug is that the sequence id of the reply sent by the x server is equal to the sequeue id of the previous cookie.

add this line to xgb/xgb.go:460

        Logger.Println("buf is ", buf)

You will know where the problem , I do not know how to fix it.

electricface commented 7 years ago

@BurntSushi

BurntSushi commented 7 years ago

@electricface I don't know when or if I'll have time to look at this. Sorry.