// Replace existing window manager func usurpWM(X *xgb.Conn, screen *xproto.ScreenInfo) { 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 { log.Fatal(err) } }
func (s *screenImpl) initWindow32() error { visualid, err := findVisual(s.xsi, 32) if err != nil { return err } colormap, err := xproto.NewColormapId(s.xc) if err != nil { return fmt.Errorf("x11driver: xproto.NewColormapId failed: %v", err) } if err := xproto.CreateColormapChecked( s.xc, xproto.ColormapAllocNone, colormap, s.xsi.Root, visualid).Check(); err != nil { return fmt.Errorf("x11driver: xproto.CreateColormap failed: %v", err) } s.window32, err = xproto.NewWindowId(s.xc) if err != nil { return fmt.Errorf("x11driver: xproto.NewWindowId failed: %v", err) } s.gcontext32, err = xproto.NewGcontextId(s.xc) if err != nil { return fmt.Errorf("x11driver: xproto.NewGcontextId failed: %v", err) } const depth = 32 xproto.CreateWindow(s.xc, depth, s.window32, s.xsi.Root, 0, 0, 1, 1, 0, xproto.WindowClassInputOutput, visualid, // The CwBorderPixel attribute seems necessary for depth == 32. See // http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32 xproto.CwBorderPixel|xproto.CwColormap, []uint32{0, uint32(colormap)}, ) xproto.CreateGC(s.xc, s.gcontext32, xproto.Drawable(s.window32), 0, nil) return nil }
func (ms Monitors) Add(e *Euclid, x XHandle, r xproto.Rectangle) *Monitor { c := x.Conn() w := x.NewWindow() n := fmt.Sprintf("%s%d", e.String("DefaultMonitorName"), ms.Number()+1) m := newMonitor(e, n, w, r) xproto.CreateWindow( c, xproto.WindowClassCopyFromParent, m.root.Window, x.Root(), r.X, r.Y, r.Width, r.Height, 0, xproto.WindowClassInputOnly, xproto.WindowClassCopyFromParent, xproto.CwEventMask, []uint32{xproto.EventMaskEnterWindow}, ) m.root.Lower() if e.Bool("FocusFollowsPointer") { m.root.Show() } ms = append(ms, m) m.focused = true return m }
// Create issues a CreateWindow request for Window. // Its purpose is to omit several boiler-plate parameters to CreateWindow // and expose the commonly useful ones. // The value mask describes which values are present in valueList. // Value masks can be found in xgb/xproto with the prefix 'Cw'. // The value list must contain values in the same order as the constants // are defined in xgb/xproto. // // For example, the following creates a window positioned at (20, 50) with // width 500 and height 700 with a background color of white. // // w, err := xwindow.Generate(X) // if err != nil { // log.Fatalf("Could not generate a new resource identifier: %s", err) // } // w.Create(X.RootWin(), 20, 50, 500, 700, // xproto.CwBackPixel, 0xffffff) func (w *Window) Create(parent xproto.Window, x, y, width, height, valueMask int, valueList ...uint32) { s := w.X.Screen() xproto.CreateWindow(w.X.Conn(), xproto.WindowClassCopyFromParent, w.Id, parent, int16(x), int16(y), uint16(width), uint16(height), 0, xproto.WindowClassInputOutput, s.RootVisual, uint32(valueMask), valueList) }
func createWindow() xproto.Window { wid, err := xproto.NewWindowId(X.Conn()) if err != nil { log.Fatal(err) } scrn := X.Screen() xproto.CreateWindow(X.Conn(), scrn.RootDepth, wid, X.RootWin(), 0, 0, 400, 400, 0, xproto.WindowClassInputOutput, scrn.RootVisual, 0, []uint32{}) return wid }
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 mkMotion(s *xproto.ScreenInfo, c *xgb.Conn) (xproto.Window, error) { motion, err := xproto.NewWindowId(c) if err != nil { return motion, err } xproto.CreateWindow( c, s.RootDepth, motion, s.Root, 0, 0, s.WidthInPixels, s.HeightInPixels, 0, xproto.WindowClassInputOnly, s.RootVisual, xproto.CwEventMask, []uint32{xproto.EventMaskPointerMotion}, ) xproto.MapWindow(c, motion) return motion, nil }
func mkMeta(s *xproto.ScreenInfo, c *xgb.Conn) (xproto.Window, error) { meta, err := xproto.NewWindowId(c) if err != nil { return meta, err } xproto.CreateWindow( c, s.RootDepth, meta, s.Root, -1, -1, 1, 1, 0, xproto.WindowClassInputOnly, s.RootVisual, 0, //xproto.CwEventMask|xproto.CwOverrideRedirect, []uint32{}, //nil, //[]uint32{1, xproto.EventMaskPropertyChange}, ) xproto.MapWindow(c, meta) return meta, nil }
func (s *screenImpl) NewWindow(opts *screen.NewWindowOptions) (screen.Window, error) { // TODO: look at opts. const width, height = 1024, 768 xw, err := xproto.NewWindowId(s.xc) if err != nil { return nil, fmt.Errorf("x11driver: xproto.NewWindowId failed: %v", err) } xg, err := xproto.NewGcontextId(s.xc) if err != nil { return nil, fmt.Errorf("x11driver: xproto.NewGcontextId failed: %v", err) } xp, err := render.NewPictureId(s.xc) if err != nil { return nil, fmt.Errorf("x11driver: render.NewPictureId failed: %v", err) } pictformat := render.Pictformat(0) switch s.xsi.RootDepth { default: return nil, fmt.Errorf("x11driver: unsupported root depth %d", s.xsi.RootDepth) case 24: pictformat = s.pictformat24 case 32: pictformat = s.pictformat32 } w := &windowImpl{ s: s, xw: xw, xg: xg, xp: xp, pump: pump.Make(), xevents: make(chan xgb.Event), } s.mu.Lock() s.windows[xw] = w s.mu.Unlock() xproto.CreateWindow(s.xc, s.xsi.RootDepth, xw, s.xsi.Root, 0, 0, width, height, 0, xproto.WindowClassInputOutput, s.xsi.RootVisual, xproto.CwEventMask, []uint32{0 | xproto.EventMaskKeyPress | xproto.EventMaskKeyRelease | xproto.EventMaskButtonPress | xproto.EventMaskButtonRelease | xproto.EventMaskPointerMotion | xproto.EventMaskExposure | xproto.EventMaskStructureNotify | xproto.EventMaskFocusChange, }, ) s.setProperty(xw, s.atomWMProtocols, s.atomWMDeleteWindow, s.atomWMTakeFocus) xproto.CreateGC(s.xc, xg, xproto.Drawable(xw), 0, nil) render.CreatePicture(s.xc, xp, xproto.Drawable(xw), pictformat, 0, nil) xproto.MapWindow(s.xc, xw) return w, nil }
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) } } }
// NewConnXgb use the specific xgb.Conn to create a new XUtil. // // NewConn, NewConnDisplay are wrapper of this function. func NewConnXgb(c *xgb.Conn) (*XUtil, error) { setup := xproto.Setup(c) screen := setup.DefaultScreen(c) // Initialize our central struct that stores everything. xu := &XUtil{ conn: c, Quit: false, Evqueue: make([]EventOrError, 0, 1000), EvqueueLck: &sync.RWMutex{}, setup: setup, screen: screen, root: screen.Root, eventTime: xproto.Timestamp(0), // last event time Atoms: make(map[string]xproto.Atom, 50), AtomsLck: &sync.RWMutex{}, AtomNames: make(map[xproto.Atom]string, 50), AtomNamesLck: &sync.RWMutex{}, Callbacks: make(map[int]map[xproto.Window][]Callback, 33), CallbacksLck: &sync.RWMutex{}, Hooks: make([]CallbackHook, 0), HooksLck: &sync.RWMutex{}, Keymap: nil, // we don't have anything yet Modmap: nil, KeyRedirect: 0, Keybinds: make(map[KeyKey][]CallbackKey, 10), KeybindsLck: &sync.RWMutex{}, Keygrabs: make(map[KeyKey]int, 10), Keystrings: make([]KeyString, 0, 10), Mousebinds: make(map[MouseKey][]CallbackMouse, 10), MousebindsLck: &sync.RWMutex{}, Mousegrabs: make(map[MouseKey]int, 10), InMouseDrag: false, MouseDragStepFun: nil, MouseDragEndFun: nil, ErrorHandler: func(err xgb.Error) { Logger.Println(err) }, } var err error = nil // Create a general purpose graphics context xu.gc, err = xproto.NewGcontextId(xu.conn) if err != nil { return nil, err } xproto.CreateGC(xu.conn, xu.gc, xproto.Drawable(xu.root), xproto.GcForeground, []uint32{xu.screen.WhitePixel}) // Create a dummy window xu.dummy, err = xproto.NewWindowId(xu.conn) if err != nil { return nil, err } xproto.CreateWindow(xu.conn, xu.Screen().RootDepth, xu.dummy, xu.RootWin(), -1000, -1000, 1, 1, 0, xproto.WindowClassInputOutput, xu.Screen().RootVisual, xproto.CwEventMask|xproto.CwOverrideRedirect, []uint32{1, xproto.EventMaskPropertyChange}) xproto.MapWindow(xu.conn, xu.dummy) // Register the Xinerama extension... because it doesn't cost much. err = xinerama.Init(xu.conn) // If we can't register Xinerama, that's okay. Output something // and move on. if err != nil { Logger.Printf("WARNING: %s\n", err) Logger.Printf("MESSAGE: The 'xinerama' package cannot be used " + "because the XINERAMA extension could not be loaded.") } return xu, nil }
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() { // 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() { // 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() { // 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 }