// Open the connection to the X server func xConnect() *xgb.Conn { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } return X }
func main(f func(screen.Screen)) (retErr error) { xc, err := xgb.NewConn() if err != nil { return fmt.Errorf("x11driver: xgb.NewConn failed: %v", err) } defer func() { if retErr != nil { xc.Close() } }() if err := render.Init(xc); err != nil { return fmt.Errorf("x11driver: render.Init failed: %v", err) } if err := shm.Init(xc); err != nil { return fmt.Errorf("x11driver: shm.Init failed: %v", err) } s, err := newScreenImpl(xc) if err != nil { return err } f(s) // TODO: tear down the s.run goroutine? It's probably not worth the // complexity of doing it cleanly, if the app is about to exit anyway. return nil }
func main() { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } // Initialize the Xinerama extension. // The appropriate 'Init' function must be run for *every* // extension before any of its requests can be used. err = xinerama.Init(X) if err != nil { log.Fatal(err) } // Issue a request to get the screen information. reply, err := xinerama.QueryScreens(X).Reply() if err != nil { log.Fatal(err) } // reply.Number is the number of active heads, while reply.ScreenInfo // is a slice of XineramaScreenInfo containing the rectangle geometry // of each head. fmt.Printf("Number of heads: %d\n", reply.Number) for i, screen := range reply.ScreenInfo { fmt.Printf("%d :: X: %d, Y: %d, Width: %d, Height: %d\n", i, screen.XOrg, screen.YOrg, screen.Width, screen.Height) } }
func (p *Power) initPlan() { p.screensaver.ConnectIdleOn(p.handleIdleOn) p.screensaver.ConnectIdleOff(p.handleIdleOff) p.updateIdletimer() con, _ := xgb.NewConn() dpms.Init(con) dpmsOn = func() { dpms.ForceLevel(con, dpms.DPMSModeOn) } dpmsOff = func() { dpms.ForceLevel(con, dpms.DPMSModeOff) } }
func NewWindowLogger(conf map[string]string) (LogGenerator, error) { x, err := xgb.NewConn() if err != nil { log.Fatal(err) } return &WindowLogger{ X11Connection: x, }, nil }
// init initializes the X connection, seeds the RNG and starts waiting // for events. func init() { var err error X, err = xgb.NewConn() if err != nil { log.Fatal(err) } rand.Seed(time.Now().UnixNano()) go grabEvents() }
func ScreenRect() (image.Rectangle, error) { c, err := xgb.NewConn() if err != nil { return image.Rectangle{}, err } defer c.Close() screen := xproto.Setup(c).DefaultScreen(c) x := screen.WidthInPixels y := screen.HeightInPixels return image.Rect(0, 0, int(x), int(y)), nil }
func NewMouse() *Mouse { mouse := &Mouse{} x11, err := xgb.NewConn() if err != nil { panic("err") } xtest.Init(x11) mouse.x11 = x11 return mouse }
func main() { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } // Get the window id of the root window. setup := xproto.Setup(X) root := setup.DefaultScreen(X).Root // Get the atom id (i.e., intern an atom) of "_NET_ACTIVE_WINDOW". aname := "_NET_ACTIVE_WINDOW" activeAtom, err := xproto.InternAtom(X, true, uint16(len(aname)), aname).Reply() if err != nil { log.Fatal(err) } // Get the atom id (i.e., intern an atom) of "_NET_WM_NAME". aname = "_NET_WM_NAME" nameAtom, err := xproto.InternAtom(X, true, uint16(len(aname)), aname).Reply() if err != nil { log.Fatal(err) } // Get the actual value of _NET_ACTIVE_WINDOW. // Note that 'reply.Value' is just a slice of bytes, so we use an // XGB helper function, 'Get32', to pull an unsigned 32-bit integer out // of the byte slice. We then convert it to an X resource id so it can // be used to get the name of the window in the next GetProperty request. reply, err := xproto.GetProperty(X, false, root, activeAtom.Atom, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() if err != nil { log.Fatal(err) } windowId := xproto.Window(xgb.Get32(reply.Value)) fmt.Printf("Active window id: %X\n", windowId) // Now get the value of _NET_WM_NAME for the active window. // Note that this time, we simply convert the resulting byte slice, // reply.Value, to a string. reply, err = xproto.GetProperty(X, false, windowId, nameAtom.Atom, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() if err != nil { log.Fatal(err) } fmt.Printf("Active window name: %s\n", string(reply.Value)) }
// Start the process of updating the status bar. genTitle will be called // repeatedly in the given interval. func Run(interval time.Duration, genTitle GenTitleFunc) { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } var status bytes.Buffer c := time.Tick(interval) for now := range c { genTitle(now, &status) setStatus(status.Bytes(), X) status.Reset() } }
func main() { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } names := seqNames(flagRequests) fcpu, err := os.Create(flagCpuProfName) if err != nil { log.Fatal(err) } defer fcpu.Close() pprof.StartCPUProfile(fcpu) defer pprof.StopCPUProfile() start := time.Now() cookies := make([]xproto.InternAtomCookie, flagRequests) for i := 0; i < flagRequests; i++ { cookies[i] = xproto.InternAtom(X, false, uint16(len(names[i])), names[i]) } for _, cookie := range cookies { cookie.Reply() } fmt.Printf("Exec time: %s\n\n", time.Since(start)) fmem, err := os.Create(flagMemProfName) if err != nil { log.Fatal(err) } defer fmem.Close() pprof.WriteHeapProfile(fmem) memStats := &runtime.MemStats{} runtime.ReadMemStats(memStats) // This isn't right. I'm not sure what's wrong. lastGcTime := time.Unix(int64(memStats.LastGC/1000000000), int64(memStats.LastGC-memStats.LastGC/1000000000)) fmt.Printf("Alloc: %d\n", memStats.Alloc) fmt.Printf("TotalAlloc: %d\n", memStats.TotalAlloc) fmt.Printf("LastGC: %s\n", lastGcTime) fmt.Printf("PauseTotalNs: %d\n", memStats.PauseTotalNs) fmt.Printf("PauseNs: %d\n", memStats.PauseNs) fmt.Printf("NumGC: %d\n", memStats.NumGC) }
func TestMain(m *testing.M) { if os.Getenv("DISPLAY") == "" { log.Printf("No X; Skipping tests") os.Exit(0) } var err error X, err = xgb.NewConn() if err != nil { log.Fatal(err) } rand.Seed(time.Now().UnixNano()) go grabEvents() os.Exit(m.Run()) }
func main() { // os.Setenv("DISPLAY", "localhost:6080") c, err := xgb.NewConn() if err != nil { fmt.Println(err) return } screen := xproto.Setup(c).DefaultScreen(c) rect := image.Rect(0, 0, int(screen.WidthInPixels), int(screen.HeightInPixels)) x, y := rect.Dx(), rect.Dy() xImg, err := xproto.GetImage(c, xproto.ImageFormatZPixmap, xproto.Drawable(screen.Root), int16(rect.Min.X), int16(rect.Min.Y), uint16(x), uint16(y), 0xffffffff).Reply() if err != nil { fmt.Println("Error: %s\r\n", err) } data := xImg.Data for i := 0; i < len(data); i += 4 { data[i], data[i+2], data[i+3] = data[i+2], data[i], 255 } img := &image.RGBA{ data, 4 * x, image.Rect(0, 0, x, y)} z.FcheckParents("screen") f := z.FileW("screen") defer f.Close() png := jpeg.Encode(f, img, &jpeg.Options{90}) fmt.Printf("End with png: %v", png) }
func main() { var serve *bool = flag.Bool("serve", false, "Listen for connections") flag.Usage = usage flag.Parse() if remote := os.Getenv("SSH_CONNECTION"); remote == "" && len(flag.Args()) != 0 { invoked_as := os.Args[0] actual_binary, err := os.Readlink("/proc/self/exe") if err != nil { log.Panic("/proc/self/exe doesn't exist!") } log.Print("Invoked as: '", invoked_as, "' (actual=", actual_binary, ")") log.Panic("Not yet implemented: Would have run locally") return } c, err := xgb.NewConn() if err != nil { log.Panic("cannot connect: %v\n", err) } s := xproto.Setup(c).DefaultScreen(c) rl_execute_reply, err := xproto.InternAtom(c, false, uint16(len(atomname)), atomname).Reply() if err != nil { panic(err) } rl_execute_atom := rl_execute_reply.Atom if *serve { //log.Printf("c = %v, s = %v, a = %v", c, s, rl_execute_atom) start_server(c, s, rl_execute_atom) } else { if len(flag.Args()) == 0 { usage() } connect(c, s, rl_execute_atom, fixup_args(flag.Args())) } }
func subscribeXEvents(ch chan<- Event, done <-chan struct{}) { X, err := xgb.NewConn() if err != nil { ch <- Event{Error: err} return } defer X.Close() if err = randr.Init(X); err != nil { ch <- Event{Error: err} return } root := xproto.Setup(X).DefaultScreen(X).Root eventMask := randr.NotifyMaskScreenChange | randr.NotifyMaskCrtcChange | randr.NotifyMaskOutputChange | randr.NotifyMaskOutputProperty err = randr.SelectInputChecked(X, root, uint16(eventMask)).Check() if err != nil { ch <- Event{Error: err} return } for { ev, err := X.WaitForEvent() select { case ch <- Event{Event: ev, Error: err}: case <-time.After(eventSendTimeout): continue case <-done: return } if err != nil { log.Fatal(err) } } }
func main() { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } err = randr.Init(X) if err != nil { log.Fatal(err) } conf := newConfig() hds := newHeads(X) if cmdInfo, ok := commands[command]; ok { cmdInfo.f(conf, hds) } else { fmt.Fprintf(os.Stderr, "Unknown command '%s'.\n", command) flag.Usage() } os.Exit(0) }
func CaptureRect(rect image.Rectangle) (*image.RGBA, error) { c, err := xgb.NewConn() if err != nil { return nil, err } defer c.Close() screen := xproto.Setup(c).DefaultScreen(c) x, y := rect.Dx(), rect.Dy() xImg, err := xproto.GetImage(c, xproto.ImageFormatZPixmap, xproto.Drawable(screen.Root), int16(rect.Min.X), int16(rect.Min.Y), uint16(x), uint16(y), 0xffffffff).Reply() if err != nil { return nil, err } data := xImg.Data for i := 0; i < len(data); i += 4 { data[i], data[i+2], data[i+3] = data[i+2], data[i], 255 } img := &image.RGBA{data, 4 * x, image.Rect(0, 0, x, y)} return img, nil }
func default1() { X, err := xgb.NewConn() if err != nil { fmt.Println(err) return } wid, _ := xproto.NewWindowId(X) screen := xproto.Setup(X).DefaultScreen(X) xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root, 0, 0, 500, 500, 0, xproto.WindowClassInputOutput, screen.RootVisual, xproto.CwBackPixel|xproto.CwEventMask, []uint32{ 0xffffffff, xproto.EventMaskStructureNotify | xproto.EventMaskKeyPress | xproto.EventMaskKeyRelease}) xproto.MapWindow(X, wid) for { ev, xerr := X.WaitForEvent() if ev == nil && xerr == nil { fmt.Println("Both event and error are nil. Exiting...") return } if ev != nil { fmt.Println("Event: %s\r\n", ev) } if xerr != nil { fmt.Println("Error: %s\r\n", xerr) } } }
func main() { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } defer X.Close() for { err = trlock.Lock(X) if err != nil { log.Fatal(err) } log.Println("Locked") time.Sleep(5 * time.Second) log.Println("Unlocking") trlock.Unlock(X) log.Println("Unlocked; ctrl-c now") time.Sleep(3 * time.Second) } }
func main() { X, _ := xgb.NewConn() // Every extension must be initialized before it can be used. err := randr.Init(X) if err != nil { log.Fatal(err) } // Get the root window on the default screen. root := xproto.Setup(X).DefaultScreen(X).Root // Gets the current screen resources. Screen resources contains a list // of names, crtcs, outputs and modes, among other things. resources, err := randr.GetScreenResources(X, root).Reply() if err != nil { log.Fatal(err) } // Iterate through all of the outputs and show some of their info. for _, output := range resources.Outputs { info, err := randr.GetOutputInfo(X, output, 0).Reply() if err != nil { log.Fatal(err) } bestMode := info.Modes[0] for _, mode := range resources.Modes { if mode.Id == uint32(bestMode) { fmt.Printf("Width: %d, Height: %d\n", mode.Width, mode.Height) } } } fmt.Println("\n") // Iterate through all of the crtcs and show some of their info. for _, crtc := range resources.Crtcs { info, err := randr.GetCrtcInfo(X, crtc, 0).Reply() if err != nil { log.Fatal(err) } fmt.Printf("X: %d, Y: %d, Width: %d, Height: %d\n", info.X, info.Y, info.Width, info.Height) } // Tell RandR to send us events. (I think these are all of them, as of 1.3.) err = randr.SelectInputChecked(X, root, randr.NotifyMaskScreenChange| randr.NotifyMaskCrtcChange| randr.NotifyMaskOutputChange| randr.NotifyMaskOutputProperty).Check() if err != nil { log.Fatal(err) } // Listen to events and just dump them to standard out. // A more involved approach will have to read the 'U' field of // RandrNotifyEvent, which is a union (really a struct) of type // RanrNotifyDataUnion. for { ev, err := X.WaitForEvent() if err != nil { log.Fatal(err) } fmt.Println(ev) } }
func main() { // Open the connection to the X server X, err := xgb.NewConn() if err != nil { log.Fatal(err) } defer X.Close() // geometric objects points := []xproto.Point{ {10, 10}, {10, 20}, {20, 10}, {20, 20}} polyline := []xproto.Point{ {50, 10}, {5, 20}, // rest of points are relative {25, -20}, {10, 10}} segments := []xproto.Segment{ {100, 10, 140, 30}, {110, 25, 130, 60}} rectangles := []xproto.Rectangle{ {10, 50, 40, 20}, {80, 50, 10, 40}} arcs := []xproto.Arc{ {10, 100, 60, 40, 0, 90 << 6}, {90, 100, 55, 40, 0, 270 << 6}} setup := xproto.Setup(X) // Get the first screen screen := setup.DefaultScreen(X) // Create black (foreground) graphic context foreground, _ := xproto.NewGcontextId(X) mask := uint32(xproto.GcForeground | xproto.GcGraphicsExposures) values := []uint32{screen.BlackPixel, 0} xproto.CreateGC(X, foreground, xproto.Drawable(screen.Root), mask, values) // Ask for our window's Id win, _ := xproto.NewWindowId(X) winDrawable := xproto.Drawable(win) // Create the window mask = uint32(xproto.CwBackPixel | xproto.CwEventMask) values = []uint32{screen.WhitePixel, xproto.EventMaskExposure} xproto.CreateWindow(X, // Connection screen.RootDepth, // Depth win, // Window Id screen.Root, // Parent Window 0, 0, // x, y 150, 150, // width, height 10, // border_width xproto.WindowClassInputOutput, // class screen.RootVisual, // visual mask, values) // masks // Map the window on the screen xproto.MapWindow(X, win) // Obey the window-delete protocol tp := "WM_PROTOCOLS" prp := "WM_DELETE_WINDOW" typeAtom, _ := xproto.InternAtom(X, true, uint16(len(tp)), tp).Reply() propertyAtom, _ := xproto.InternAtom(X, true, uint16(len(prp)), prp).Reply() // It turns out that we need the window ID as a byte-stream... WTF!! // xprop.ChangeProp(xu, win, 8, "WM_NAME", "STRING", ([]byte)(name)) // ChangeProp(xu *xgbutil.XUtil, win xproto.Window, format byte, prop string, typ string, data []byte) data := make([]byte, 4) xgb.Put32(data, uint32(propertyAtom.Atom)) xproto.ChangeProperty(X, xproto.PropModeReplace, win, typeAtom.Atom, xproto.AtomAtom, 32, 1, data) for { evt, err := X.WaitForEvent() fmt.Printf("An event of type %T occured.\n", evt) if evt == nil && err == nil { fmt.Println("Exiting....") return } else if err != nil { log.Fatal(err) } switch event := evt.(type) { case xproto.ExposeEvent: /* We draw the points */ xproto.PolyPoint(X, xproto.CoordModeOrigin, winDrawable, foreground, points) /* We draw the polygonal line */ xproto.PolyLine(X, xproto.CoordModePrevious, winDrawable, foreground, polyline) /* We draw the segments */ xproto.PolySegment(X, winDrawable, foreground, segments) /* We draw the rectangles */ xproto.PolyRectangle(X, winDrawable, foreground, rectangles) /* We draw the arcs */ xproto.PolyArc(X, winDrawable, foreground, arcs) case xproto.ClientMessageEvent: if len(event.Data.Data32) > 0 { data := xproto.Atom(event.Data.Data32[0]) if data == propertyAtom.Atom { return } else { atomName, _ := xproto.GetAtomName(X, data).Reply() fmt.Println(atomName.Name) } } else { atomName, _ := xproto.GetAtomName(X, event.Type).Reply() fmt.Println(atomName.Name) } default: /* Unknown event type, ignore it */ } } return }
// Listen ... func Listen(fn func(e Event)) error { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } setup := xproto.Setup(X) root := setup.DefaultScreen(X).Root var prevWindowID xproto.Window var prevClasses []string for { <-time.After(msRefresh * time.Millisecond) // From one of the xgb examples. aname := "_NET_ACTIVE_WINDOW" activeAtom, err := xproto.InternAtom(X, true, uint16(len(aname)), aname).Reply() if err != nil { log.Println(err) continue } reply, err := xproto.GetProperty(X, false, root, activeAtom.Atom, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() if err != nil { log.Println(err) continue } windowID := xproto.Window(xgb.Get32(reply.Value)) aname = "WM_CLASS" nameAtom, err := xproto.InternAtom(X, true, uint16(len(aname)), aname).Reply() if err != nil { log.Println(err) continue } reply, err = xproto.GetProperty(X, false, windowID, nameAtom.Atom, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() if err != nil { log.Println(err) continue } classes := stringSlice(reply.Value) // Check if active window has changed since last time. if windowID != prevWindowID { fn(Lost{ WMClass: prevClasses, }) fn(Gained{ WMClass: classes, }) prevWindowID = windowID prevClasses = classes } } }
func main() { /* Loading config */ if err := config.Load(config.ConfigPath()); err != nil { fmt.Printf("Error when loading config : %v\n", err) return } /* Opening the connection */ var conn *xgb.Conn if c, err := xgb.NewConn(); err != nil { fmt.Printf("Error when connecting to x11 server : %v\n", err) return } else { conn = c } defer conn.Close() /* Loading screens configuration */ if err := screens.Load(conn); err != nil { fmt.Printf("Error while getting screens configuration : %v\n", err) return } /* Loading window manager */ if err := window.Load(conn); err != nil { fmt.Printf("Error while loading window manager : %v\n", err) return } /* Opening the fifo */ var pipe *fifo.Fifo if p, err := fifo.Open(); err != nil { fmt.Printf("Error while opening the fifo : %s\n", err) return } else { pipe = p } defer pipe.Close() cmds := [...]fifo.Command{ &KillCommand{}, &RedrawCommand{}, &CloseCommand{false, false, 0}, &NotifCommand{0, "", ""}, } for _, cmd := range cmds { pipe.AddCmd(cmd) } /* Opening the queue */ var notifs *queue.Queue if q, err := queue.Open(conn); err != nil { fmt.Printf("Error while opening the queue : %s\n", err) return } else { notifs = q } /* Main loop */ orders := make(chan types.Order, 10) go xloop(conn, orders) go pipe.ReadOrders(orders) notifs.Run(orders) }
func main() { // Open the connection to the X server X, err := xgb.NewConn() if err != nil { log.Fatal(err) } defer X.Close() setup := xproto.Setup(X) // Get the first screen screen := setup.DefaultScreen(X) // Replace existing window manager wmName := fmt.Sprintf("WM_S%d", X.DefaultScreen) managerAtom, err := xproto.InternAtom(X, true, uint16(len(wmName)), wmName).Reply() if err != nil { log.Fatal(err) } fakeWindow, _ := xproto.NewWindowId(X) xproto.CreateWindow(X, // Connection screen.RootDepth, // Depth fakeWindow, // Window Id screen.Root, // Parent Window -1000, -1000, // x, y 1, 1, // width, height 0, // border_width xproto.WindowClassInputOutput, // class screen.RootVisual, // visual xproto.CwEventMask|xproto.CwOverrideRedirect, []uint32{1, xproto.EventMaskPropertyChange}) // masks xproto.MapWindow(X, fakeWindow) err = xproto.SetSelectionOwnerChecked(X, fakeWindow, managerAtom.Atom, xproto.TimeCurrentTime).Check() if err != nil { fmt.Println("foo") log.Fatal(err) } arcs := []xproto.Arc{ {10, 100, 60, 40, 0, 90 << 6}, {90, 100, 55, 40, 0, 270 << 6}} // Create black (foreground) graphic context foreground, _ := xproto.NewGcontextId(X) mask := uint32(xproto.GcForeground | xproto.GcGraphicsExposures) values := []uint32{screen.BlackPixel, 0} xproto.CreateGC(X, foreground, xproto.Drawable(screen.Root), mask, values) // Ask for our window's Id win, _ := xproto.NewWindowId(X) winDrawable := xproto.Drawable(win) // Create the window mask = uint32(xproto.CwBackPixel | xproto.CwEventMask) values = []uint32{screen.WhitePixel, xproto.EventMaskExposure} xproto.CreateWindow(X, // Connection screen.RootDepth, // Depth win, // Window Id screen.Root, // Parent Window 0, 0, // x, y 150, 150, // width, height 10, // border_width xproto.WindowClassInputOutput, // class screen.RootVisual, // visual mask, values) // masks // Map the window on the screen xproto.MapWindow(X, win) // Obey the window-delete protocol tp := "WM_PROTOCOLS" prp := "WM_DELETE_WINDOW" typeAtom, _ := xproto.InternAtom(X, true, uint16(len(tp)), tp).Reply() propertyAtom, _ := xproto.InternAtom(X, true, uint16(len(prp)), prp).Reply() data := make([]byte, 4) xgb.Put32(data, uint32(propertyAtom.Atom)) xproto.ChangeProperty(X, xproto.PropModeReplace, win, typeAtom.Atom, xproto.AtomAtom, 32, 1, data) // Main loop for { evt, err := X.WaitForEvent() fmt.Printf("An event of type %T occured.\n", evt) if evt == nil && err == nil { fmt.Println("Exiting....") return } else if err != nil { log.Fatal(err) } switch event := evt.(type) { case xproto.ExposeEvent: /* We draw the arcs */ xproto.PolyArc(X, winDrawable, foreground, arcs) case xproto.ClientMessageEvent: if len(event.Data.Data32) > 0 { data := xproto.Atom(event.Data.Data32[0]) if data == propertyAtom.Atom { return } else { atomName, _ := xproto.GetAtomName(X, data).Reply() fmt.Println(atomName.Name) } } else { atomName, _ := xproto.GetAtomName(X, event.Type).Reply() fmt.Println(atomName.Name) } default: /* Unknown event type, ignore it */ } } return }
func main() { X, err := xgb.NewConn() if err != nil { fmt.Println(err) return } wid, _ := xproto.NewWindowId(X) screen := xproto.Setup(X).DefaultScreen(X) xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root, 0, 0, 240, 240, 0, xproto.WindowClassInputOutput, screen.RootVisual, xproto.CwBackPixel|xproto.CwEventMask, []uint32{ // values must be in the order defined by the protocol 0xffffffff, xproto.EventMaskStructureNotify | xproto.EventMaskKeyPress | xproto.EventMaskKeyRelease}) xproto.MapWindow(X, wid) fmt.Printf("%d %d\n", screen.AllowedDepths[0].Visuals[0].VisualId, screen.RootVisual) var ( ux, uy float64 = 1, 1 fe cairo.FontExtents te cairo.TextExtents text = "joy" x, y, px, dashlength float64 ) surface := cairo.NewSurfaceFromXCB(xproto.Drawable(wid), screen.AllowedDepths[0].Visuals[0], 240, 240) surface.Scale(240, 240) surface.SetFontSize(0.5) /* Drawing code goes here */ surface.SetSourceRGB(0.0, 0.0, 0.0) surface.SelectFontFace("Georgia", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) surface.FontExtents(&fe) ux, uy = surface.DeviceToUserDistance(ux, uy) if ux > uy { px = ux } else { px = uy } surface.FontExtents(&fe) surface.TextExtents(text, &te) x = 0.5 - te.X_bearing - te.Width/2 y = 0.5 - fe.Descent + fe.Height/2 /* baseline, descent, ascent, height */ surface.SetLineWidth(4 * px) dashlength = 9 * px surface.SetDash([]float64{dashlength}, 0) surface.SetSourceRGBA(0, 0.6, 0, 0.5) surface.MoveTo(x+te.X_bearing, y) surface.RelLineTo(te.Width, 0) surface.MoveTo(x+te.X_bearing, y+fe.Descent) surface.RelLineTo(te.Width, 0) surface.MoveTo(x+te.X_bearing, y-fe.Ascent) surface.RelLineTo(te.Width, 0) surface.MoveTo(x+te.X_bearing, y-fe.Height) surface.RelLineTo(te.Width, 0) surface.Stroke() /* extents: width & height */ surface.SetSourceRGBA(0, 0, 0.75, 0.5) surface.SetLineWidth(px) dashlength = 3 * px surface.SetDash([]float64{dashlength}, 0) surface.Rectangle(x+te.X_bearing, y+te.Y_bearing, te.Width, te.Height) surface.Stroke() /* text */ surface.MoveTo(x, y) surface.SetSourceRGB(0, 0, 0) surface.ShowText(text) /* bearing */ surface.SetDash(nil, 0) surface.SetLineWidth(2 * px) surface.SetSourceRGBA(0, 0, 0.75, 0.5) surface.MoveTo(x, y) surface.RelLineTo(te.X_bearing, te.Y_bearing) surface.Stroke() /* text's advance */ surface.SetSourceRGBA(0, 0, 0.75, 0.5) surface.Arc(x+te.X_advance, y+te.Y_advance, 5*px, 0, 2*math.Pi) surface.Fill() /* reference point */ surface.Arc(x, y, 5*px, 0, 2*math.Pi) surface.SetSourceRGBA(0.75, 0, 0, 0.5) surface.Fill() surface.Finish() surface.Destroy() for { ev, xerr := X.WaitForEvent() if ev == nil && xerr == nil { // fmt.Println("Both event and error are nil. Exiting...") return } if ev != nil { // fmt.Printf("Event: %s\n", ev) } if xerr != nil { // fmt.Printf("Error: %s\n", xerr) } } }
func main() { // Open the connection to the X server X, err := xgb.NewConn() if err != nil { log.Fatal(err) } // geometric objects points := []xproto.Point{ {10, 10}, {10, 20}, {20, 10}, {20, 20}} polyline := []xproto.Point{ {50, 10}, {5, 20}, // rest of points are relative {25, -20}, {10, 10}} segments := []xproto.Segment{ {100, 10, 140, 30}, {110, 25, 130, 60}} rectangles := []xproto.Rectangle{ {10, 50, 40, 20}, {80, 50, 10, 40}} arcs := []xproto.Arc{ {10, 100, 60, 40, 0, 90 << 6}, {90, 100, 55, 40, 0, 270 << 6}} setup := xproto.Setup(X) // Get the first screen screen := setup.DefaultScreen(X) // Create black (foreground) graphic context foreground, _ := xproto.NewGcontextId(X) mask := uint32(xproto.GcForeground | xproto.GcGraphicsExposures) values := []uint32{screen.BlackPixel, 0} xproto.CreateGC(X, foreground, xproto.Drawable(screen.Root), mask, values) // Ask for our window's Id win, _ := xproto.NewWindowId(X) winDrawable := xproto.Drawable(win) // Create the window mask = uint32(xproto.CwBackPixel | xproto.CwEventMask) values = []uint32{screen.WhitePixel, xproto.EventMaskExposure} xproto.CreateWindow(X, // Connection screen.RootDepth, // Depth win, // Window Id screen.Root, // Parent Window 0, 0, // x, y 150, 150, // width, height 10, // border_width xproto.WindowClassInputOutput, // class screen.RootVisual, // visual mask, values) // masks // Map the window on the screen xproto.MapWindow(X, win) for { evt, err := X.WaitForEvent() switch evt.(type) { case xproto.ExposeEvent: /* We draw the points */ xproto.PolyPoint(X, xproto.CoordModeOrigin, winDrawable, foreground, points) /* We draw the polygonal line */ xproto.PolyLine(X, xproto.CoordModePrevious, winDrawable, foreground, polyline) /* We draw the segments */ xproto.PolySegment(X, winDrawable, foreground, segments) /* We draw the rectangles */ xproto.PolyRectangle(X, winDrawable, foreground, rectangles) /* We draw the arcs */ xproto.PolyArc(X, winDrawable, foreground, arcs) default: /* Unknown event type, ignore it */ } if err != nil { log.Fatal(err) } } return }
func main() { X, err := xgb.NewConn() if err != nil { fmt.Println(err) return } // xproto.Setup retrieves the Setup information from the setup bytes // gathered during connection. setup := xproto.Setup(X) // This is the default screen with all its associated info. screen := setup.DefaultScreen(X) // Any time a new resource (i.e., a window, pixmap, graphics context, etc.) // is created, we need to generate a resource identifier. // If the resource is a window, then use xproto.NewWindowId. If it's for // a pixmap, then use xproto.NewPixmapId. And so on... wid, _ := xproto.NewWindowId(X) // CreateWindow takes a boatload of parameters. xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root, 0, 0, 500, 500, 0, xproto.WindowClassInputOutput, screen.RootVisual, 0, []uint32{}) // This call to ChangeWindowAttributes could be factored out and // included with the above CreateWindow call, but it is left here for // instructive purposes. It tells X to send us events when the 'structure' // of the window is changed (i.e., when it is resized, mapped, unmapped, // etc.) and when a key press or a key release has been made when the // window has focus. // We also set the 'BackPixel' to white so that the window isn't butt ugly. xproto.ChangeWindowAttributes(X, wid, xproto.CwBackPixel|xproto.CwEventMask, []uint32{ // values must be in the order defined by the protocol 0xffffffff, xproto.EventMaskStructureNotify | xproto.EventMaskKeyPress | xproto.EventMaskKeyRelease}) // MapWindow makes the window we've created appear on the screen. // We demonstrated the use of a 'checked' request here. // A checked request is a fancy way of saying, "do error handling // synchronously." Namely, if there is a problem with the MapWindow request, // we'll get the error *here*. If we were to do a normal unchecked // request (like the above CreateWindow and ChangeWindowAttributes // requests), then we would only see the error arrive in the main event // loop. // // Typically, checked requests are useful when you need to make sure they // succeed. Since they are synchronous, they incur a round trip cost before // the program can continue, but this is only going to be noticeable if // you're issuing tons of requests in succession. // // Note that requests without replies are by default unchecked while // requests *with* replies are checked by default. err = xproto.MapWindowChecked(X, wid).Check() if err != nil { fmt.Printf("Checked Error for mapping window %d: %s\n", wid, err) } else { fmt.Printf("Map window %d successful!\n", wid) } // This is an example of an invalid MapWindow request and what an error // looks like. err = xproto.MapWindowChecked(X, 0).Check() if err != nil { fmt.Printf("Checked Error for mapping window 0x1: %s\n", err) } else { // neva fmt.Printf("Map window 0x1 successful!\n") } // Start the main event loop. for { // WaitForEvent either returns an event or an error and never both. // If both are nil, then something went wrong and the loop should be // halted. // // An error can only be seen here as a response to an unchecked // request. ev, xerr := X.WaitForEvent() if ev == nil && xerr == nil { fmt.Println("Both event and error are nil. Exiting...") return } if ev != nil { fmt.Printf("Event: %s\n", ev) } if xerr != nil { fmt.Printf("Error: %s\n", xerr) } } }
func main() { var err error xConn, err = xgb.NewConn() if err != nil { log.Fatal(err) } if err = xinerama.Init(xConn); err != nil { log.Fatal(err) } xSetup := xp.Setup(xConn) if len(xSetup.Roots) != 1 { log.Fatalf("X setup has unsupported number of roots: %d", len(xSetup.Roots)) } rootXWin = xSetup.Roots[0].Root becomeTheWM() initAtoms() initDesktop(&xSetup.Roots[0]) initKeyboardMapping() initScreens() // Manage any existing windows. if tree, err := xp.QueryTree(xConn, rootXWin).Reply(); err != nil { log.Fatal(err) } else if tree != nil { for _, c := range tree.Children { if c == desktopXWin { continue } attrs, err := xp.GetWindowAttributes(xConn, c).Reply() if attrs == nil || err != nil { continue } if attrs.OverrideRedirect || attrs.MapState == xp.MapStateUnmapped { continue } manage(c, false) } } // Process X events. eeChan := make(chan xEventOrError) go func() { for { e, err := xConn.WaitForEvent() eeChan <- xEventOrError{e, err} } }() for { for i, c := range checkers { if err := c.Check(); err != nil { log.Println(err) } checkers[i] = nil } checkers = checkers[:0] select { case f := <-proactiveChan: f() case ee := <-eeChan: if ee.error != nil { log.Println(ee.error) continue } switch e := ee.event.(type) { case xp.ButtonPressEvent: eventTime = e.Time handleButtonPress(e) case xp.ButtonReleaseEvent: eventTime = e.Time case xp.ClientMessageEvent: // No-op. case xp.ConfigureNotifyEvent: // No-op. case xp.ConfigureRequestEvent: handleConfigureRequest(e) case xp.DestroyNotifyEvent: // No-op. case xp.EnterNotifyEvent: eventTime = e.Time handleEnterNotify(e) case xp.ExposeEvent: handleExpose(e) case xp.KeyPressEvent: eventTime, keyRootX, keyRootY, keyState = e.Time, e.RootX, e.RootY, e.State handleKeyPress(e) case xp.KeyReleaseEvent: eventTime, keyRootX, keyRootY, keyState = e.Time, 0, 0, 0 case xp.MapNotifyEvent: // No-op. case xp.MappingNotifyEvent: // No-op. case xp.MapRequestEvent: manage(e.Window, true) case xp.MotionNotifyEvent: eventTime = e.Time handleMotionNotify(e) case xp.UnmapNotifyEvent: unmanage(e.Window) default: log.Printf("unhandled event: %v", ee.event) } } } }