forked from BurntSushi/xgb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
reworking xgb. cleaned up connection stuff a little. making new xid g…
…eneration cleaner and use goroutines for it.
- Loading branch information
Andrew Gallant (Ocelot)
authored and
Andrew Gallant (Ocelot)
committed
May 4, 2012
1 parent
9028aaf
commit 9f44c62
Showing
5 changed files
with
317 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package xgb | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"io" | ||
"net" | ||
"os" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// connect connects to the X server given in the 'display' string. | ||
// If 'display' is empty it will be taken from os.Getenv("DISPLAY"). | ||
// Note that you should read and understand the "Connection Setup" of the | ||
// X Protocol Reference Manual before changing this function: | ||
// http://goo.gl/4zGQg | ||
func (c *Conn) connect(display string) error { | ||
err := c.dial(display) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Get authentication data | ||
authName, authData, err := readAuthority(c.host, c.display) | ||
noauth := false | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Could not get authority info: %v\n", err) | ||
fmt.Fprintf(os.Stderr, "Trying connection without authority info...\n") | ||
authName = "" | ||
authData = []byte{} | ||
noauth = true | ||
} | ||
|
||
// Assume that the authentication protocol is "MIT-MAGIC-COOKIE-1". | ||
if !noauth && (authName != "MIT-MAGIC-COOKIE-1" || len(authData) != 16) { | ||
return errors.New("unsupported auth protocol " + authName) | ||
} | ||
|
||
buf := make([]byte, 12+pad(len(authName))+pad(len(authData))) | ||
buf[0] = 0x6c | ||
buf[1] = 0 | ||
Put16(buf[2:], 11) | ||
Put16(buf[4:], 0) | ||
Put16(buf[6:], uint16(len(authName))) | ||
Put16(buf[8:], uint16(len(authData))) | ||
Put16(buf[10:], 0) | ||
copy(buf[12:], []byte(authName)) | ||
copy(buf[12+pad(len(authName)):], authData) | ||
if _, err = c.conn.Write(buf); err != nil { | ||
return err | ||
} | ||
|
||
head := make([]byte, 8) | ||
if _, err = io.ReadFull(c.conn, head[0:8]); err != nil { | ||
return err | ||
} | ||
code := head[0] | ||
reasonLen := head[1] | ||
major := Get16(head[2:]) | ||
minor := Get16(head[4:]) | ||
dataLen := Get16(head[6:]) | ||
|
||
if major != 11 || minor != 0 { | ||
return errors.New(fmt.Sprintf("x protocol version mismatch: %d.%d", | ||
major, minor)) | ||
} | ||
|
||
buf = make([]byte, int(dataLen)*4+8, int(dataLen)*4+8) | ||
copy(buf, head) | ||
if _, err = io.ReadFull(c.conn, buf[8:]); err != nil { | ||
return err | ||
} | ||
|
||
if code == 0 { | ||
reason := buf[8 : 8+reasonLen] | ||
return errors.New(fmt.Sprintf("x protocol authentication refused: %s", | ||
string(reason))) | ||
} | ||
|
||
ReadSetupInfo(buf, &c.Setup) | ||
|
||
if c.defaultScreen >= len(c.Setup.Roots) { | ||
c.defaultScreen = 0 | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *Conn) dial(display string) error { | ||
if len(display) == 0 { | ||
display = os.Getenv("DISPLAY") | ||
} | ||
|
||
display0 := display | ||
if len(display) == 0 { | ||
return errors.New("empty display string") | ||
} | ||
|
||
colonIdx := strings.LastIndex(display, ":") | ||
if colonIdx < 0 { | ||
return errors.New("bad display string: " + display0) | ||
} | ||
|
||
var protocol, socket string | ||
|
||
if display[0] == '/' { | ||
socket = display[0:colonIdx] | ||
} else { | ||
slashIdx := strings.LastIndex(display, "/") | ||
if slashIdx >= 0 { | ||
protocol = display[0:slashIdx] | ||
c.host = display[slashIdx+1 : colonIdx] | ||
} else { | ||
c.host = display[0:colonIdx] | ||
} | ||
} | ||
|
||
display = display[colonIdx+1 : len(display)] | ||
if len(display) == 0 { | ||
return errors.New("bad display string: " + display0) | ||
} | ||
|
||
var scr string | ||
dotIdx := strings.LastIndex(display, ".") | ||
if dotIdx < 0 { | ||
c.display = display[0:] | ||
} else { | ||
c.display = display[0:dotIdx] | ||
scr = display[dotIdx+1:] | ||
} | ||
|
||
dispnum, err := strconv.Atoi(c.display) | ||
if err != nil || dispnum < 0 { | ||
return errors.New("bad display string: " + display0) | ||
} | ||
|
||
if len(scr) != 0 { | ||
c.defaultScreen, err = strconv.Atoi(scr) | ||
if err != nil { | ||
return errors.New("bad display string: " + display0) | ||
} | ||
} | ||
|
||
// Connect to server | ||
if len(socket) != 0 { | ||
c.conn, err = net.Dial("unix", socket+":"+c.display) | ||
} else if len(c.host) != 0 { | ||
if protocol == "" { | ||
protocol = "tcp" | ||
} | ||
c.conn, err = net.Dial(protocol, c.host+":"+strconv.Itoa(6000+dispnum)) | ||
} else { | ||
c.conn, err = net.Dial("unix", "/tmp/.X11-unix/X"+c.display) | ||
} | ||
|
||
if err != nil { | ||
return errors.New("cannot connect to " + display0 + ": " + err.Error()) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package main | ||
|
||
import ( | ||
// "fmt" | ||
"log" | ||
|
||
"github.com/BurntSushi/xgb" | ||
) | ||
|
||
func init() { | ||
log.SetFlags(0) | ||
} | ||
|
||
func main() { | ||
X, err := xgb.NewConn() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
aname := "_NET_ACTIVE_WINDOW" | ||
atom, err := X.InternAtom(true, uint16(len(aname)), aname) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
log.Printf("%d", atom.Atom) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/BurntSushi/xgb" | ||
) | ||
|
||
func init() { | ||
log.SetFlags(0) | ||
} | ||
|
||
func get32(buf []byte) uint32 { | ||
v := uint32(buf[0]) | ||
v |= uint32(buf[1]) << 8 | ||
v |= uint32(buf[2]) << 16 | ||
v |= uint32(buf[3]) << 24 | ||
return v | ||
} | ||
|
||
func main() { | ||
X, err := xgb.NewConn() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
root := X.DefaultScreen().Root | ||
|
||
aname := "_NET_ACTIVE_WINDOW" | ||
atom, err := X.InternAtom(true, uint16(len(aname)), aname) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
reply, err := X.GetProperty(false, root, atom.Atom, xgb.GetPropertyTypeAny, | ||
0, (1<<32)-1) | ||
log.Printf("%X", get32(reply.Value)) | ||
} | ||
|
Oops, something went wrong.