// Listen will tell X to report events corresponding to the event masks // provided for the given window. If a call to Listen is omitted, you will // not receive the events you desire. // Event masks are constants declare in the xgb/xproto package starting with the // EventMask prefix. func (w *Window) Listen(evMasks ...int) { evMask := 0 for _, mask := range evMasks { evMask |= mask } xproto.ChangeWindowAttributes(w.X.Conn(), w.Id, xproto.CwEventMask, []uint32{uint32(evMask)}) }
// XSurfaceSet will set the given window's background to this image's pixmap. // Note that an image can have multiple surfaces, which is why the window // id still needs to be passed to XPaint. A call to XSurfaceSet simply tells // X that the window specified should use the pixmap in Image as its // background image. // Note that XSurfaceSet cannot be called on a sub-image. (An error will be // returned if you do.) // XSurfaceSet will also allocate an X pixmap if one hasn't been created for // this image yet. // (Generating a pixmap id can cause an error, so this call could return // an error.) func (im *Image) XSurfaceSet(wid xproto.Window) error { if im.Subimg { return fmt.Errorf("XSurfaceSet cannot be called on sub-images." + "Please set the surface using the original parent image.") } if im.Pixmap == 0 { if err := im.CreatePixmap(); err != nil { return err } } // Tell the surface (window) to use this pixmap. xproto.ChangeWindowAttributes(im.X.Conn(), wid, xproto.CwBackPixmap, []uint32{uint32(im.Pixmap)}) return nil }
// Change issues a ChangeWindowAttributes request with the provided mask // and value list. Please see Window.Create for an example on how to use // the mask and value list. func (w *Window) Change(valueMask int, valueList ...uint32) { xproto.ChangeWindowAttributes(w.X.Conn(), w.Id, uint32(valueMask), valueList) }
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) } } }