github.com/robotn/xgb@v0.0.0-20190912153532-2cb92d044934/examples/create-window/main.go (about)

     1  // Example create-window shows how to create a window, map it, resize it,
     2  // and listen to structure and key events (i.e., when the window is resized
     3  // by the window manager, or when key presses/releases are made when the
     4  // window has focus). The events are printed to stdout.
     5  package main
     6  
     7  import (
     8  	"fmt"
     9  
    10  	"github.com/robotn/xgb"
    11  	"github.com/robotn/xgb/xproto"
    12  )
    13  
    14  func main() {
    15  	X, err := xgb.NewConn()
    16  	if err != nil {
    17  		fmt.Println(err)
    18  		return
    19  	}
    20  
    21  	// xproto.Setup retrieves the Setup information from the setup bytes
    22  	// gathered during connection.
    23  	setup := xproto.Setup(X)
    24  
    25  	// This is the default screen with all its associated info.
    26  	screen := setup.DefaultScreen(X)
    27  
    28  	// Any time a new resource (i.e., a window, pixmap, graphics context, etc.)
    29  	// is created, we need to generate a resource identifier.
    30  	// If the resource is a window, then use xproto.NewWindowId. If it's for
    31  	// a pixmap, then use xproto.NewPixmapId. And so on...
    32  	wid, _ := xproto.NewWindowId(X)
    33  
    34  	// CreateWindow takes a boatload of parameters.
    35  	xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root,
    36  		0, 0, 500, 500, 0,
    37  		xproto.WindowClassInputOutput, screen.RootVisual, 0, []uint32{})
    38  
    39  	// This call to ChangeWindowAttributes could be factored out and
    40  	// included with the above CreateWindow call, but it is left here for
    41  	// instructive purposes. It tells X to send us events when the 'structure'
    42  	// of the window is changed (i.e., when it is resized, mapped, unmapped,
    43  	// etc.) and when a key press or a key release has been made when the
    44  	// window has focus.
    45  	// We also set the 'BackPixel' to white so that the window isn't butt ugly.
    46  	xproto.ChangeWindowAttributes(X, wid,
    47  		xproto.CwBackPixel|xproto.CwEventMask,
    48  		[]uint32{ // values must be in the order defined by the protocol
    49  			0xffffffff,
    50  			xproto.EventMaskStructureNotify |
    51  				xproto.EventMaskKeyPress |
    52  				xproto.EventMaskKeyRelease})
    53  
    54  	// MapWindow makes the window we've created appear on the screen.
    55  	// We demonstrated the use of a 'checked' request here.
    56  	// A checked request is a fancy way of saying, "do error handling
    57  	// synchronously." Namely, if there is a problem with the MapWindow request,
    58  	// we'll get the error *here*. If we were to do a normal unchecked
    59  	// request (like the above CreateWindow and ChangeWindowAttributes
    60  	// requests), then we would only see the error arrive in the main event
    61  	// loop.
    62  	//
    63  	// Typically, checked requests are useful when you need to make sure they
    64  	// succeed. Since they are synchronous, they incur a round trip cost before
    65  	// the program can continue, but this is only going to be noticeable if
    66  	// you're issuing tons of requests in succession.
    67  	//
    68  	// Note that requests without replies are by default unchecked while
    69  	// requests *with* replies are checked by default.
    70  	err = xproto.MapWindowChecked(X, wid).Check()
    71  	if err != nil {
    72  		fmt.Printf("Checked Error for mapping window %d: %s\n", wid, err)
    73  	} else {
    74  		fmt.Printf("Map window %d successful!\n", wid)
    75  	}
    76  
    77  	// This is an example of an invalid MapWindow request and what an error
    78  	// looks like.
    79  	err = xproto.MapWindowChecked(X, 0).Check()
    80  	if err != nil {
    81  		fmt.Printf("Checked Error for mapping window 0x1: %s\n", err)
    82  	} else { // neva
    83  		fmt.Printf("Map window 0x1 successful!\n")
    84  	}
    85  
    86  	// Start the main event loop.
    87  	for {
    88  		// WaitForEvent either returns an event or an error and never both.
    89  		// If both are nil, then something went wrong and the loop should be
    90  		// halted.
    91  		//
    92  		// An error can only be seen here as a response to an unchecked
    93  		// request.
    94  		ev, xerr := X.WaitForEvent()
    95  		if ev == nil && xerr == nil {
    96  			fmt.Println("Both event and error are nil. Exiting...")
    97  			return
    98  		}
    99  
   100  		if ev != nil {
   101  			fmt.Printf("Event: %s\n", ev)
   102  		}
   103  		if xerr != nil {
   104  			fmt.Printf("Error: %s\n", xerr)
   105  		}
   106  	}
   107  }